home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
287_02
/
graduser.doc
< prev
next >
Wrap
Text File
|
1989-05-23
|
183KB
|
5,382 lines
GRAD Graphics Library User's Manual
Version 1.1
for IBM PC/XT/AT or compatibles
June 07, 1987
By Conrad Kwok
Table of Contents
1 Introduction . . . . . . . . . . . . . . . . . . . . . . 1
1.1 General Information . . . . . . . . . . . . . . . . 1
1.2 Licence . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Future Enhancements . . . . . . . . . . . . . . . . 3
2 How to use GRAD . . . . . . . . . . . . . . . . . . . . 4
2.1 Compile and Link . . . . . . . . . . . . . . . . . . 4
2.2 Interpretation . . . . . . . . . . . . . . . . . . . 6
3 The GRAD Frame . . . . . . . . . . . . . . . . . . . . . 7
3.1 Related Functions . . . . . . . . . . . . . . . . . 7
3.1.1 CreateFrame . . . . . . . . . . . . . . . . . . 7
3.1.2 SelectFrame . . . . . . . . . . . . . . . . . . 8
3.1.3 RemvFrame . . . . . . . . . . . . . . . . . . . 8
4 Coordinate System . . . . . . . . . . . . . . . . . . . 10
4.1 Physical Coordinate System . . . . . . . . . . . . . 10
4.2 Logical Coordinate System . . . . . . . . . . . . . 10
4.2.1 Setting Origin . . . . . . . . . . . . . . . . 10
4.2.2 Translation . . . . . . . . . . . . . . . . . . 11
4.2.3 Windowing . . . . . . . . . . . . . . . . . . . 11
4.3 Related Functions . . . . . . . . . . . . . . . . . 11
4.3.1 SetOrg . . . . . . . . . . . . . . . . . . . . 12
4.3.2 RelOrg . . . . . . . . . . . . . . . . . . . . 12
4.4 Summary . . . . . . . . . . . . . . . . . . . . . . 12
5 Setting Window . . . . . . . . . . . . . . . . . . . . . 13
5.1 Function Description . . . . . . . . . . . . . . . . 13
5.1.1 ResetWin . . . . . . . . . . . . . . . . . . . 13
5.1.2 SetWin . . . . . . . . . . . . . . . . . . . . 13
5.2 Example . . . . . . . . . . . . . . . . . . . . . . 14
6 GRAD Environment . . . . . . . . . . . . . . . . . . . . 15
6.1 Functions Description . . . . . . . . . . . . . . . 15
6.1.1 EnvSave . . . . . . . . . . . . . . . . . . . . 15
6.1.2 EnvRsto . . . . . . . . . . . . . . . . . . . . 16
7 Selection of Plot Type . . . . . . . . . . . . . . . . . 16
7.1 Related Function . . . . . . . . . . . . . . . . . . 17
7.1.1 PlotType . . . . . . . . . . . . . . . . . . . 17
8 Dot Plotting and Line Drawing . . . . . . . . . . . . . 18
8.1 Functions Description . . . . . . . . . . . . . . . 18
8.1.1 Dot . . . . . . . . . . . . . . . . . . . . . . 18
8.1.2 SetStyle . . . . . . . . . . . . . . . . . . . 18
8.1.3 HorzLine . . . . . . . . . . . . . . . . . . . 19
8.1.4 VertLine . . . . . . . . . . . . . . . . . . . 19
8.2 Efficiency Consideration . . . . . . . . . . . . . . 20
9 Circle, Ellipse and Arc . . . . . . . . . . . . . . . . 21
9.1 Functions Description . . . . . . . . . . . . . . . 21
9.1.1 Circle . . . . . . . . . . . . . . . . . . . . 21
9.1.2 Ellipse . . . . . . . . . . . . . . . . . . . . 22
9.1.3 FillCircle . . . . . . . . . . . . . . . . . . 22
9.1.4 FillEllipse . . . . . . . . . . . . . . . . . . 23
9.1.5 Arc1 . . . . . . . . . . . . . . . . . . . . . 23
9.1.6 Earc1 . . . . . . . . . . . . . . . . . . . . . 24
9.1.7 Arc2 . . . . . . . . . . . . . . . . . . . . . 25
9.1.8 Earc2 . . . . . . . . . . . . . . . . . . . . . 26
9.1.9 ArcPoint . . . . . . . . . . . . . . . . . . . 27
9.2 Hints . . . . . . . . . . . . . . . . . . . . . . . 27
10 4-connected Region Filling . . . . . . . . . . . . . . . 29
10.1 Functions Description . . . . . . . . . . . . . . . 29
10.1.1 SolidFill . . . . . . . . . . . . . . . . . . 29
10.1.2 PatternFill . . . . . . . . . . . . . . . . . 30
10.2 Hints . . . . . . . . . . . . . . . . . . . . . . . 31
11 Text Characters Related Functions . . . . . . . . . . . 32
Introduction . . . . . . . . . . . . . . . . . . . . . . 32
11.1 Functions Description . . . . . . . . . . . . . . . 32
11.1.1 LoadFont . . . . . . . . . . . . . . . . . . . 32
11.1.2 SelectFont . . . . . . . . . . . . . . . . . . 33
11.1.3 RemvFont . . . . . . . . . . . . . . . . . . . 33
11.1.4 WriteStr . . . . . . . . . . . . . . . . . . . 34
11.1.5 ReadStr . . . . . . . . . . . . . . . . . . . 36
11.1.6 NextXY . . . . . . . . . . . . . . . . . . . . 37
12 Block Operations . . . . . . . . . . . . . . . . . . . . 38
12.1 Function Description . . . . . . . . . . . . . . . 38
12.1.1 BlockCopy . . . . . . . . . . . . . . . . . . 38
12.1.2 BlockSave . . . . . . . . . . . . . . . . . . 39
12.1.3 BlockLoad . . . . . . . . . . . . . . . . . . 39
13 Frame Printing . . . . . . . . . . . . . . . . . . . . . 41
13.1 Function Description . . . . . . . . . . . . . . . 41
13.1.1 PrintFrame . . . . . . . . . . . . . . . . . . 41
14 The DRAW function . . . . . . . . . . . . . . . . . . . 44
14.1 Draw . . . . . . . . . . . . . . . . . . . . . . . 44
15 Miscellaneous Functions . . . . . . . . . . . . . . . . 48
15.1 Functions Description . . . . . . . . . . . . . . . 48
15.1.1 GRADinit . . . . . . . . . . . . . . . . . . . 48
15.1.2 cleanup . . . . . . . . . . . . . . . . . . . 48
15.1.3 XHLine . . . . . . . . . . . . . . . . . . . . 49
15.1.4 writec . . . . . . . . . . . . . . . . . . . . 49
16 Advance Functions . . . . . . . . . . . . . . . . . . . 51
16.1 Functions Description . . . . . . . . . . . . . . . 51
16.1.1 calcaddr . . . . . . . . . . . . . . . . . . . 51
16.1.2 exchange . . . . . . . . . . . . . . . . . . . 51
16.1.3 fr_read . . . . . . . . . . . . . . . . . . . 52
16.1.4 fr_write . . . . . . . . . . . . . . . . . . . 52
16.1.5 phyaddr . . . . . . . . . . . . . . . . . . . 52
16.1.6 writetype . . . . . . . . . . . . . . . . . . 53
17 System Dependent Functions . . . . . . . . . . . . . . . 54
17.1 Functions Description . . . . . . . . . . . . . . . 54
17.1.1 settext . . . . . . . . . . . . . . . . . . . 54
17.1.2 setgraph . . . . . . . . . . . . . . . . . . . 54
17.1.3 initjlsr . . . . . . . . . . . . . . . . . . . 54
17.1.4 cleanjlsr . . . . . . . . . . . . . . . . . . 55
17.1.5 dumpjlsr . . . . . . . . . . . . . . . . . . . 55
18 GRAD Global Variables . . . . . . . . . . . . . . . . . 56
18.1 TEN_MS . . . . . . . . . . . . . . . . . . . . . . 56
18.2 DOTVALUE . . . . . . . . . . . . . . . . . . . . . 56
18.3 PRE_GRAD_ERR_LEVEL, POST_GRAD_ERR_LEVEL . . . . . . 56
18.4 PRE_ERROR_FUNC, POST_ERROR_FUNC . . . . . . . . . . 56
18.5 SPACING_FUNC . . . . . . . . . . . . . . . . . . . 57
18.6 XLIMIT, YLIMIT . . . . . . . . . . . . . . . . . . 57
18.7 ORGX, ORGY . . . . . . . . . . . . . . . . . . . . 57
18.8 WINX1, WINX2, WINY1, WINY2 . . . . . . . . . . . . 58
19 Advance Topics . . . . . . . . . . . . . . . . . . . . . 59
19.1 Error Handling . . . . . . . . . . . . . . . . . . 59
19.2 Using SPACING_FUNC . . . . . . . . . . . . . . . . 60
20 Sample Programs . . . . . . . . . . . . . . . . . . . . 62
20.1 MPrint and Interp . . . . . . . . . . . . . . . . . 62
20.2 Rotate . . . . . . . . . . . . . . . . . . . . . . 63
20.3 Size . . . . . . . . . . . . . . . . . . . . . . . 64
20.4 DispFont . . . . . . . . . . . . . . . . . . . . . 64
20.5 SwPrt (Sideway) . . . . . . . . . . . . . . . . . . 64
20.6 Tex2GRAD . . . . . . . . . . . . . . . . . . . . . 65
Appendix A : Customizing of Printer Control Codes . . . . . 67
General Information . . . . . . . . . . . . . . . . . . . 67
EPSON FX-80 Driver Case Study . . . . . . . . . . . . . . 69
OKI ML192 Driver Case Study . . . . . . . . . . . . . . . 69
Additional Information . . . . . . . . . . . . . . . . . 70
Appendix B : Customizing of Output Device . . . . . . . . . 71
Appendix C : Font File Structure . . . . . . . . . . . . . . 72
Fixed Size Character (type 0) . . . . . . . . . . . . . . 72
Variable Size Character (type 1) . . . . . . . . . . . . 73
Appendix D : Block File Structure . . . . . . . . . . . . . 74
Appendix E : Functions Summary . . . . . . . . . . . . . . . 75
Appendix F : System Limits . . . . . . . . . . . . . . . . . 76
Program Limits . . . . . . . . . . . . . . . . . . . . . 76
Configuration Limits . . . . . . . . . . . . . . . . . . 76
Appendix G : Error Messages . . . . . . . . . . . . . . . . 78
Appendix H : List of Header Files . . . . . . . . . . . . . 79
GRAD User's Manual June 7, 1987
1 Introduction
1.1 General Information
GRAD is a graphics functions library for program compiled
with Microsoft C compiler V4.0 in small model. The library
contains most functions you normally expected in a graphics
library plus a number of unique features.
This brief summary is to introduce you features in GRAD
version 1.1. Each of these features is described in detail in the
documentation.
a. GRAD supports color graphics card in 640 X 200 graphics
mode, Hercules 720 X 348 graphics mode and JLASER (2560 X
3162). Other output device can be configured.
b. It can create multiple virtual screens of very large size.
which is limited by memory. That means you can create
graphics even you do not have a graphics display screen.
c. Functions are provided to maintain windows.
d. Nearly all low level functions are written in assembly
language to provide speed. The result below is obtained by
running the program BRENCH on an AT compatible (8MHz, 1 wait
state). All library functions when compiled with Microsoft C
compiler use 8088 codes option. All times are in
millisecond.
Hercules Card Virtual Screen
a loop 0.0023 0.0023
Horizontal Line 0.38 0.27
(length 300)
Horiz. Line width 20 6.2 4.3
Vertical Line 8.5 5.7
(length 300)
Vert. Line width 2 8.5 5.7
Vert. Line width 32 17.0 11.3
Circle radius 100 25.5 28.3
Ellipse both axes
is 100 pixels 30.5 33.3
When drawing a horizontal line, it takes about 1 microsecond
per pixel on average!
e. The whole library use integer arithmetic only. This
guarantees high speed operations when executed without math
coprocessor and keep the program size small.
f. Besides simple functions such as dot, line, circle, ellipse
...etc., high speed arc drawing and region filling functions
are also included.
g. Screen printing is provided as standard function in GRAD.
Many different options are provided such as different
printing density and mixed printing of text and graphics.
- 1 -
GRAD User's Manual June 7, 1987
h. GRAD provides functions for high speed and high quality text
display.
i. The whole screen or part of a screen can be saved, loaded or
copied.
Several sample programs with practical value are included
such as sideway printing and text and graphics merge printing
programs.
1.2 Licence
You may freely copy and distribute the GRAD library and
related programs for non-commerical use only.
If you find this library and the related programs useful, a
contribution of $20 or whatever you think it worth will be
appreciated.
- 2 -
GRAD User's Manual June 7, 1987
[EMPTY]
- 3 -
GRAD User's Manual June 7, 1987
2 How to use GRAD
There are two ways to use the GRAD functions. The obvious is
to write a program that use the GRAD functions and then compile
and link with GRAD library. Another way is to write a GRAD
command file that call GRAD functions using syntax similar to C
function call. Then use the supplied program interp or Mprint to
interpret the file.
The first way (compile and link) requires longer time but it
may use the full power of C and GRAD functions. The second way
(interpretation) limits the user to simple graphics drawing but
the advantage is no compilation and link is necessary. Hence it
is good for simple drawings and debug a drawing before including
in the final C program.
The compile and link method will be described in detail in
this chapter. The interpretation method will only be described
briefly in the chapter. Details can be found in the user's guide
for interp and Mprint in the later chapter.
Before we go on and try the first example, I want to tell
you if you don't like to see any error message (in text form or
in bit mapped form) when the program is in graphics mode, you
want redirect the output from the file to any file you like.
2.1 Compile and Link
Knowledge of Microsoft C compiler Version 4.0 is
assumed and small model library must be installed
Below is a very simple program that draws a dot only. Use
your favorite editor to enter the program below and name the
program as "onedot.c".
#include <stdio.h>
main ()
{
GradInit(); /* (1) */
setgraph(); /* (2) */
Dot(100,100); /* (3) */
getch(); /* (4) */
settext(); /* (5) */
cleanup(0); /* (6) */
}
Then compile and link the program using the command line:
cl /AS /J onedot.c /link GRADLIB
If you don't have any typing mistakes and GRADLIB is in
current directory or in the directory specified in the LIB
environment variable, you should get the file onedot.exe without
- 4 -
GRAD User's Manual June 7, 1987
getting an error message. If you get any error, go back and check
the program and make sure that the GRADLIB is properly installed.
Otherwise, you may go ahead and execute the program "onedot.exe".
About one to two seconds later, the screen will be cleared
and you should find a single dot. Pressing any key will terminate
the program and the screen will return to text mode.
Using the GRAD library is simple. Now let's return to the
source listing and examine it line by line. In the program, we
called 3 GRAD functions and 2 system dependent functions and 1 C
library function.
(1) GRADinit is to initialize the GRAD environment. Now it only
performs a processor speed test and assign the result to the
global variable TEN_MS. Time dependent functions may do
adjustment according to the its value such that they behave
the same on different speed computers. Actually we don't need
GRADinit in this case but we should always include that for
future compatibility.
(2) setgraph is not a standard GRAD function. It is system
dependent function. It is only necessary if you want to use
the default configured graphics screen. Its function is to
change the display mode to graphics and clear the screen.
(3) Dot is a GRAD function that plot a single dot. Dot(100,100)
means plot a dot at coordinate (100,100).
(4) getch is a C library function that reads the next key pressed
on the keyboard.
(5) settext again is not a standard GRAD function. It is used to
change the display mode back to text mode.
(6) cleanup is contrary to GRADinit. It should be called before
exit. If the parameter to cleanup is non-zero, cleanup will
execute exit with the parameter as exit code. If the
parameter is zero, it will return to the caller.
Instead of using command line to do compile and link, we can
also use make file to do the same job. Below is an example:
OPTIMIZE=/Ox
OPTIONS=/AS /J $(OPTIMIZE)
.asm.obj:
masm /ML $*;
.c.obj:
msc $(OPTION) $*;
onedot.obj: onedot.c
onedot.exe: onedot.obj
link onedot,onedot,nul,GRADLIB;
- 5 -
GRAD User's Manual June 7, 1987
2.2 Interpretation
The one line file below will perform exactly the same as
our "onedot" program in the last section by using interp to
interpret it.
Dot(100,100);
Let's suppose the file above is called "onedot.gcm". To interpret
the file by interp, type
interp onedot.gcm
The syntax required by interp is described in a later chapter.
- 6 -
GRAD User's Manual June 7, 1987
3 The GRAD Frame
A frame is a memory area where the graphics image is stored.
It can be any size (there are some limitations and they will
discuss in next section) but it must be an rectangle. Each bit of
the memory corresponds to a pixel. The memory area can be video
memory or computer working memory. If it is video memory, the
graphics image can be seen on screen. If it is working memory,
the frame becomes a virtual graphics screen. The graphics image
can only be seen by dumping to the printer or copying to the
video memory.
More than one frame can exist simultaneously within GRAD.
However only one frame can be active at one time. Usually the
graphics video memory is predefined as the first frame and this
is the default active frame. It is a permanent frame so it cannot
be removed by GRAD function RemvFrame which will be described in
next section also.
If you are the first time reading this manual, you may skip
over this chapter and consider the video memory as the only frame
available. All functions that apply to the video memory frame can
be applied to the other frames in the same way.
3.1 Related Functions
3.1.1 CreateFrame
frame_number=CreateFrame(horizontal,vertical);
int frame_number, horizontal, vertical;
RETURN VALUE
A frame number.
DESCRIPTION
The CreateFrame function will create a frame of size
specified by the two parameters. However, the horizontal size
must be an integral multiply of 16. If it is not, the horizontal
size will be rounded up.
Note that the maximum physical coordinate number will be one
less than the actual size because coordinate number starts at 0.
POSSIBLE ERROR CONDITION
a. Insufficient Memory
Program will terminate.
b. Too many frame exist
The maximum number of frame allowed is an system parameter. If
the number is exceed, the program will terminate.
EXAMPLE
frame=CreateFrame(640,200);
- 7 -
GRAD User's Manual June 7, 1987
FUNCTIONS INCLUDED
RemvFrame
3.1.2 SelectFrame
ret=SelectFrame(frame);
int ret, frame;
RETURN VALUE
It will return the active frame number just before the
execution of SelectFrame if frame number given is valid and the
frame exist. Otherwise -1 will be returned and the active frame
is not changed.
DESCRIPTION
The function SelectFrame select the current active frame.
Furthermore, the drawing window and point of origin will reset to
the same as last time when the frame is deselected. If the frame
is the first time selected after it is created, the origin will
be physical coordinate (0,0) and the window size is same as the
frame size.
EXAMPLE
if ((old_frame=SelectFrame(frame))==(-1))
printf("Frame does not exist\n");
. . .
. . . Draw in the new frame
. . .
SelectFrame(old_frame); /* switch back to the */
/* original frame */
FUNCTIONS INCLUDED
SelectFont
3.1.3 RemvFrame
ret=RemvFrame(frame);
int ret, frame;
RETURN VALUE
A return value of 0 means successful. A return value of -1
means the frame does not exist. If the frame type is permanent, 0
will be returned but the frame can still be selected.
DESCRIPTION
The function RemvFrame will remove the frame from GRAD. The
memory occupied by the frame will be deallocated.
- 8 -
GRAD User's Manual June 7, 1987
EXAMPLE
If (RemvFrame(frame)==(-1))
printf("Frame does not exist\n");
FUNCTIONS INCLUDED
CreateFrame
- 9 -
GRAD User's Manual June 7, 1987
4 Coordinate System
4.1 Physical Coordinate System
Each Frame can be viewed as a two dimensional plane composes
of identical rectangular pixels. Each pixel is in of the two
states -- on or off (set or reset). If a pixel is on, it is
represented by a dot on screen or on printer paper or a logical
high state in memory.
To address a pixel, we can use x and y coordinate numbers.
It is usually represented as (x,y). the top right corner of a
frame is defined as the origin of the physical coordinate system
which as 0 x and y coordinate value (i.e. (0,0)). The x
coordinate of a pixel on the same horizontal line increase as we
move right. The y coordinate of a pixel on the same vertical line
increase as we move downwards. This is different from the
coordinate system we usually used which has y coordinate increase
as we move upwards.
The maximum value of the coordinate numbers are limited by
the size of a frame. For example, the number of pixels on IBM
color graphics adapter are 640 (horizontal) and 200 (vertical).
Therefore legal x and y coordinate numbers are 0 to 639 and 0 to
199 respectively.
Physical coordinate numbers are only used in one external
interface function. All other functions use logical coordinate
numbers which will be described in the next section.
4.2 Logical Coordinate System
Logical coordinate system provides a convenient way to look
at your frame. Initially, the logical coordinate numbers are the
same as the physical coordinate number. The relationship can be
changed using SetOrg and RelOrg functions which will be described
later.
The relationship between logical and physical coordinate
system can be described in several ways and different way of
thinking helps in different situation. So I will describe all
three ways I can think of.
4.2.1 Setting Origin
The logical coordinate system has the same size as the
physical coordinate system. Each pixel is one-one corresponding
between the two systems. The difference is that any pixels within
the logical coordinate system can be defined as the origin.
Suppose your frame size is 640 by 200. You can define
(300,100) in physical coordinate system as the origin in the
logical coordinate system. The legal range of logical coordinate
numbers will be -320 to +319 and -100 to +99 for the x and y
coordinates respectively. Any attempt to write outside the legal
space will be ignored.
- 10 -
GRAD User's Manual June 7, 1987
It is legal to define a point outside the physical
coordinate system as the origin. For example, you can
define (-10,-10) as the origin. Legal coordinate number
for x and y axes will be 10 to 649 and 10 to 209
respectively.
4.2.2 Translation
The logical and physical coordinate numbers are offset by
fixed numbers specified by you.
An example of this situation is when several identical
figures are required to draw on the frame. Instead of repeating
the calling sequence with different coordinate numbers, we can
create a subroutine including the functions for drawing one
figure. We call the same subroutine as many times as required and
set different translation values in between two calls.
4.2.3 Windowing
Try to imagine you are standing before a large square dinner
table. On the table, there is a piece of paper (normal size) with
its sides parallel to the edges of the table. You are holding a
special pen will only leave mark on the paper only but not on the
table. You can draw anywhere on the table. However, only those
drawings passing the paper can be seen.
This is an analogy of the relationship between the physical
and logical coordinate system. The dinner table is the logical
coordinate system space, the paper is the physical coordinate
system (or frame) and the GRAD functions are the pen. You can
place the frame anywhere within the logical coordinate space.
The x and y coordinate numbers in the logical coordinate
space must be in the range of -32768 to +32767.
4.3 Related Functions
There are two functions for the control of the coordinate
system. They are:
SetOrg(x,y) Set the point (x,y) in the physical coordinate
system as the origin in the logical coordinate
system.
RelOrg(x,y) Set the point (x,y) in the logical coordinate
system as the new origin in the logical
coordinate system.
- 11 -
GRAD User's Manual June 7, 1987
4.3.1 SetOrg
SetOrg(x,y);
int x,y;
a. If you consider the logical coordinate system as described in
4.2.1, to set (x,y) as the origin, the function call required
is:
SetOrg(x,y);
b. If you consider the logical coordinate system as described in
4.2.2, to set a and b pixels of translation in x and y axes
will require the function call:
SetOrg(a,b);
c. If you consider the logical coordinate system as described in
4.2.3 and you want to place the upper left corner of the frame
at (u,v) of the logical space, the function call required is:
SetOrg(-u,-v);
FUNCTIONS INCLUDED
RelOrg, SetWin, ResetWin
4.3.2 RelOrg
The function of RelOrg is exactly the same as SetOrg except
the parameter specified is add to the existing setting instead of
replacing the settings.
4.4 Summary
All coordinate number described in this manual except in
this chapter are logical coordinate numbers unless otherwise
specified. Initially, the physical and logical coordinate numbers
are the same. If you do not change it by one of the functions
SetOrg and RelOrg, they are equivalent.
The x coordinate number increase as it move to the right and
the y coordinate number increase as it move downwards. The top
left corner of a frame is the origin (0,0) of the physical
coordinate system.
- 12 -
GRAD User's Manual June 7, 1987
5 Setting Window
Windowing is one of the most important features provided in
GRAD. Every function described in this manual which may change
the frame in any way is affected by the window setting. Only
those changes which are inside the window are permitted. Any
attempt to change any pixels outside the window are ignored.
The pixels outside the window are essentially frozen. They
are unable to change the state until they are un-frozen.
Therefore it is easy to create several windows in the frame
which are logically separated from each others. Furthermore
additional routines are provided to facilitate the writing of
application which need to maintain several window in the frame.
A simple example of creating and maintaining windows are
included later in this chapter.
Only 2 functions in GRAD are directly related to windowing
(but most functions in GRAD are indirectly related to it). They
are:
ResetWin Reset the window size to frame size
SetWin Set the window to the desired size
5.1 Function Description
5.1.1 ResetWin
ResetWin()
RETURN VALUE
none
DESCRIPTION
Reset the window size to the current frame size.
EXAMPLE
ResetWin();
FUNCTIONS INCLUDED
SetWin, SetOrg, RelOrg
5.1.2 SetWin
SetWin(x1,y1,x2,y2);
int x1,y2,x2,y2;
RETURN VALUE
none
DESCRIPTION
- 13 -
GRAD User's Manual June 7, 1987
A window must be rectangular in shape. (x1,y1) and (x2,y2)
are coordinates of the opposite corners of the window. The order
is not important. Both (x1,y1) and (x2,y2) are included in the
window.
If (x1,y1) and/or (x2,y2) is/are outside the frame, the
window set will be the area of the window within the frame.
EXAMPLE
SetWin(100,100,200,200);
The width and height of the window are both 101 pixels.
FUNCTIONS INCLUDED
ResetWin, RelOrg, SetOrg
5.2 Example
/* Below is code segment in C demostrating the use of window. */
/* Some of the functions are not yet discussed. So you may */
/* wish to skip this section for the first reading. */
ResetWin();
PlotType(1);
HorzLine(-10000,-10000,20000,20000); /* Clear Frame */
PlotType(0); /* select OR type */
SetOrg(99,19);
Rectangle(0,0,203,103); /* A rectangle enclosing the window */
RelOrg(1,1); /* top-left-hand corner of the window */
SetWin(0,0,200,100); /* set window */
window1=EnvSave(0); /* save all the environment setting */
SetOrg(400,20); /* move to the second window */
SetWin(0,0,100,100); /* set window */
HorzLine(0,0,1000,1000); /* Set all the pixels inside window */
PlotType(1); /* select AND type */
window2=EnvSave(0); /* save all the settings */
Circle(50,50,80); /* setting is not affected, draws in window2 */
Line(0,0,200,200);
Line(100,0,0,100);
EnvRsto(window1,KEEP_SLOT); /* restore environment of window1 */
WriteStr(0,LEFT,0,10,
"The drawing in this frame is completely unaffected",0,0);
WriteStr(0,LEFT,0,20,
"By the drawing in the other frame.",0,0);
EnvRsto(window2,KEEP_SLOT); /* back to window2 */
SolidFill(40,50);
EnvRsto(window1,KEEP_SLOT); /* back to window1 */
WriteStr(0,LEFT,0,50,
"You may switch back and forth between the 2 window",0,0);
- 14 -
GRAD User's Manual June 7, 1987
6 GRAD Environment
Several parameters of GRAD has global effect. For examples,
plot type, frame number, window setting, ...et cetera. These
settings are called the environment of GRAD.
Sometimes, one may wish to save the current environment
settings and restore it later. For instances when several windows
are using at the same time.
GRAD provides two functions to save and restore these
environment settings. You may selectively restore some or all the
settings. Those two functions are:
EnvSave Save the current environment
EnvRsto Restore the environment saved
6.1 Functions Description
6.1.1 EnvSave
EnvSave(slot_nu);
int slot_nu;
RETURN VALUE
0 means no more slot available. All other positive number
means environment is save in the that slot number.
DESCRIPTION
slot_nu can be from 0 to the maximum slot number. If slot_nu
number is 0, EnvSave will search for an empty slot. If none is
found, 0 will be returned otherwise the slot number used will be
returned.
When a slot number is given, current environment will be
saved in that slot number even if that slot is used. This
provides a means to dedicate a certain slot number for a
particular application. Contents can be changed without worrying
about any change of slot number.
The following settings are save by EnvSave: frame number,
window coordinates, origin, plot type, style and font number.
EnvSave will not change any of the settings.
Note : When you change active frame, both the origin and window
setting are saved. When the frame is re-selected, they
will be restored. See also SelectFrame
EXAMPLES
EnvSave(0);
Save the current environment in the next unused slot.
FUNCTIONS INCLUDED
EnvRsto
- 15 -
GRAD User's Manual June 7, 1987
6.1.2 EnvRsto
EnvRsto(slot_nu, options);
int slot_nu, options;
RETURN VALUE
none
DESCRIPTION
EnvRsto will restore all or partial environment settings
saved in the slot. The slot number should be a value returned by
EnvSave. However, slot number 0 has special meaning. If 0 is
given, the environment settings at the time when the program is
first started are restored.
The default options are to restore all settings and release
the slot. You may change the default by using the following
options. (The definition of the option can be found in the file
GRADENV.H)
KEEP_SLOT do not release the slot
KEEP_WIN keep the current window setting
KEEP_ORG keep the current origin
KEEP_STYLE keep the current plot style
KEEP_PLOTTYPE keep the current plot type
KEEP_FRAME keep the current active frame
KEEP_FONT keep the current font
To combine more than 1 options, use bitwise OR operator '|'.
EXAMPLE
EnvRsto(0);
Restore all default settings.
FUNCTIONS INCLUDED
EnvSave
7 Selection of Plot Type
Each pixel in the frame must be in one of the two states --
either set or reset. When GRAD draws in the frame, it can force a
pixel to set or reset or reverse the state. In GRAD terminology,
the three types of operations are called OR, AND and XOR. Their
function codes are 0, 1 and 2 respectively.
Code Type Description
0 OR Force a pixel to set state
1 AND Force a pixel to reset state
2 XOR Reverse the state of a pixel
Every GRAD function which draws to the frame is affected by
the current plot type. The default plot type is OR. The name of
the function to change the plot type is PlotType which will be
described in next section.
- 16 -
GRAD User's Manual June 7, 1987
7.1 Related Function
7.1.1 PlotType
ret=PlotType(type);
int ret, type;
RETURN VALUE
The plot type (between 0 and 3) used before this function is
executed.
DESCRIPTION
Set the plot type according to the table below:
Code Type Description
0 OR Force a pixel to set state
1 AND Force a pixel to reset state
2 XOR Reverse the state of a pixel
3 OR same as type 0
If the type specified is greater than 3, then it will take
module 4 of the value given and set according to the table above.
EXAMPLE
PlotType(0);
FUNCTIONS INCLUDED
none
- 17 -
GRAD User's Manual June 7, 1987
8 Dot Plotting and Line Drawing
This chapter will describe the following functions:
Dot(x,y)
Plot a single dot
SetStyle(style)
Set the line style
HorzLine(x,y,length,width)
Draws a horizontal line starting from (x,y) in the
direction of increasing x. The width of the line extend
in the direction of increasing y.
VertLine(x,y,length,width)
Draws a vertical line starting from (x,y) in the
direction of increasing y. The width of the line extend
in the direction of increasing x.
8.1 Functions Description
8.1.1 Dot
Dot(x,y);
int x,y;
RETURN VALUE
none
DESCRIPTION
It plot a dot at location (x,y) of current active frame.
EXAMPLE
Dot(10,10)
FUNCTIONS INCLUDED
HorzLine, VertLine
8.1.2 SetStyle
old=SetStyle(style);
unsigned int style, old;
RETURN VALUE
return the old style setting
DESCRIPTION
It sets the style of the line drawn by HorzLine, VertLine,
Line, Arc1, Arc2, Earc1 and Earc2. Style is a 16-bit value.
Default is 0xffff. That means the lines drawn are solid line.
When you call SetStyle, it just move the value of the parameter
- 18 -
GRAD User's Manual June 7, 1987
to a internal variable except when the value is 0. In that case,
the original value will be inverted. (i.e. exclusive or with
0xffff).
EXAMPLES
oldstyle=SetStyle(0xffff); /* save original style */
HorzLine(0,0,100,1);
SetStyle(0x3333);
HorzLine(0,10,100,1);
SetStyle(0);
HorzLine(0,20,100,1);
SetStyle(0x11ff);
HorzLine(0,30,100,1);
SetStyle(oldstyle); /* restore original style */
The first line is a solid line. The second and third example
draw 2 dotted lines with 2 dots in every 4 dot position. However
the ink dots position are complementary of each other. The fourth
example draw a mixed of dotted and dashed line.
FUNCTIONS INCLUDED
none
8.1.3 HorzLine
HorzLine(x,y,length,width);
int x,y,length,width;
RETURN VALUE
none
DESCRIPTION
It draws a horizontal line (i.e. parallel to x axis)
starting from the point (x,y) in the increasing direction of x
coordinate. If the length or width is less than or equal to zero,
nothing will be drawn. The width of the line will extend in the
increasing direction of y coordinate. The line drawn is affected
by the style set by SetStyle.
EXAMPLE
HorzLine(100,100,100,2);
Draws a line of length 100 pixels and width is 2. That means
a total of 200 pixels are drawn.
FUNCTIONS INCLUDED
Dot, VertLine
8.1.4 VertLine
VertLine(x,y,length,width);
int x,y,length,width;
RETURN VALUE
- 19 -
GRAD User's Manual June 7, 1987
none
DESCRIPTION
It draws a vertical line (i.e. parallel to y axis) starting
from the point (x,y) in the increasing direction of y coordinate.
If the length or width is less than or equal to zero, nothing
will be drawn. The width of the line extends in the increasing
direction of x coordinate. The line drawn is affected by the
STYLE set by SetStyle.
EXAMPLE
VertLine(100,100,100,2);
Draws a line of length 100 pixels and width is 2. That means
a total of 200 pixels are drawn.
FUNCTIONS INCLUDED
Dot, HorzLine
8.2 Efficiency Consideration
HorzLine and VertLine never call Dot to draw line. They use
a much faster method to draw line. Therefore, it is much longer
to plot 100 consecutive dots than draw a 100 pixels long vertical
or horizontal line.
HorzLine in general draws faster than VertLine in drawing
lines with same length and width. Therefore if you want to draw a
block with length and width approximately the same, it is better
to use HorzLine. However, if the style setting is not 0xffff, the
result by HorzLine and VertLine are different.
- 20 -
GRAD User's Manual June 7, 1987
9 Circle, Ellipse and Arc
GRAD library provides extensive support for drawing circles,
ellipses and arcs.
The circle command in some programs or libraries actually
draws a polygon. That may look like a circle when the desired
circle is small. But when the desired circle is large, the output
will not be a circle any more.
The circle and ellipse function in GRAD draw `true' circles
and ellipses. What it means is then the circles and ellipses when
displayed or printed on a media with aspect ratio equal to 1
(i.e. the width and height of a pixel is equal), each pixel of
the circles or ellipses is less than or equal to half pixel
distance from a real circle or ellipse with the same size.
Furthermore, each pixel will be adjacent to 2 and only 2 pixels
of the circle or ellipse. So the region enclosed can be filled
using the fill command.
The functions that will be described in this chapter are:
Circle Draws a logical circle
Ellipse Draws a logical ellipse
FillCircle Draws a disc
FillEllipse Draws a elliptical disc
Arc1 Arc drawing 1
Earc1 Elliptical arc drawing 1
Arc2 Arc drawing 2
Earc2 Elliptical arc drawing 2
ArcPoint Gives the coordinates of 2 end points
of Arc2 or Earc2
Since the aspect ratio of the output device may not be 1.
The circle drawn by Circle may not look like a circle on output.
If you want to get `circle' in the output, you should draw an
ellipse with appropriate ratio of horizontal and vertical axes
specified. For example, the width of a pixel is twice of the
height of the pixel on a certain output device. In order to get a
`circle', the length of the horizontal axis should be half of the
vertical axis.
9.1 Functions Description
9.1.1 Circle
Circle(center_x, center_y, radius);
int center_x, center_y, radius;
RETURN VALUE
none
DESCRIPTION
This function will draw a logical circle. radius is in term
of pixels and must be greater than or equal to 0. The circle draw
is not affected by the plot style setting. (See also Arc1 and
Arc2)
- 21 -
GRAD User's Manual June 7, 1987
EXAMPLE
Circle(100,100,20);
Assume the window is larger than the circle. Then the left
most, right most, top and bottom points of the circle will be
(80,100), (120,100), (100,80) and (100,120) respectively.
FUNCTIONS INCLUDED
Arc1
9.1.2 Ellipse
Ellipse(center_x, center_y, horiz_axis, vert_axis);
int center_x, center_y, horiz_axis, vert_axis;
RETURN VALUE
none
DESCRIPTION
This function will draw an ellipse. horiz_axis is the
distance in pixel from the center to the left most or right most
point of the ellipse. vert_axis is the distance from the center
to the top or bottom point of the ellipse. If horiz_axis and
vert_axis is equal, the result will be the same as using Circle
will radius set to either horiz_axis or vert_axis. The ellipse
drawn is not affected by the plot style. (See also Earc1 and
Earc2)
EXAMPLE
Ellipse(100,100,40,20);
FUNCTIONS INCLUDED
Earc1
9.1.3 FillCircle
FillCircle(center_x, center_y, radius);
int center_x, center_y, radius;
RETURN VALUE
none
DESCRIPTION
This function is same as Circle except that the circle drawn
will be filled.
EXAMPLE
FillCircle(100,100,20);
- 22 -
GRAD User's Manual June 7, 1987
Assume the window is larger than the circle. Then the left
most, right most, top and bottom points of the circle will be
(80,100), (120,100), (100,80) and (100,120) respectively.
FUNCTIONS INCLUDED
FillEllipse, HorzLine, VertLine
9.1.4 FillEllipse
FillEllipse(center_x, center_y, horiz_axis, vert_axis);
int center_x, center_y, horiz_axis, vert_axis;
RETURN VALUE
none
DESCRIPTION
This function is same as Ellipse except that the output will
be an filled ellipse.
EXAMPLE
FillEllipse(100,100,40,20);
FUNCTIONS INCLUDED
FillCircle, HorzLine, VertLine
9.1.5 Arc1
Arc1(center_x, center_y, radius, arc_spec);
int center_x, center_y, radius, arc_spec;
RETURN VALUE
none
DESCRIPTION
In the function Arc1, a circle is divided into 8 equal parts
as defined later. You may select any part or parts of the circle
to draw. Moreover, the arcs drawn are affected by the line style
selected.
8 equal parts of the circle is obtained by drawing
horizontal, vertical and 2 diagonal lines (slope is 1 and -1)
through the center of the circle. You specify which part of the
circle is required in the parameter arc_spec.
The name of the eight parts are defined as follows (in
clockwise direction):
UP_RIGHT, RIGHT_UP, RIGHT_DOWN, DOWN_RIGHT, DOWN_LEFT,
LEFT_DOWN, LEFT_UP and UP_LEFT.
Additional constants defined include:
UPPER_HALF = RIGHT_UP | UP_RIGHT | UP_LEFT | LEFT_UP
- 23 -
GRAD User's Manual June 7, 1987
LOWER_HALF = LEFT_DOWN | DOWN_LEFT | DOWN_RIGHT | RIGHT_DOWN
LEFT_HALF = UP_LEFT | LEFT_UP | LEFT_DOWN | DOWN_LEFT
RIGHT_HALF = DOWN_RIGHT | RIGHT_DOWN | RIGHT_UP | UP_RIGHT
These constants can be found in the header file GRADARC.H
As mentioned above, the arc drawn is affected by the plot
style selected. Due to the way a circle is drawn, the style of
the arc may not be uniform. The result would be better if the
style setting is symmetrical. (i.e. the bits when read from left
to right or right to left are the same)
EXAMPLES
(1) Arc1(50,50,30,UPPER_HALF);
(2) SetStyle(0xc3c3);
Arc1(100,100,30,UPPER_HALF | LOWER_HALF);
First example will draw the upper half of the circle only.
The second example will draw the whole circle but the
circumference is drawn in dotted line style.
FUNCTIONS INCLUDED
Circle
9.1.6 Earc1
Earc1(center_x, center_y, horiz_axis, vert_axis,
arc_spec);
int center_x, center_y, horiz_axis, vert_axis, arc_spec;
RETURN VALUE
none
DESCRIPTION
Earc1 is very similar to Arc1. Earc1 draws a arc of an
ellipse instead of a arc of a circle. The ellipse is still
divided into 8 region. The four lines to divide the ellipse are a
horizontal line, a vertical line and two lines joining the points
which slope of the tangent is 1 and -1 respectively. Each line
must go through the center. If you do not understand how the
ellipse is divided, just try some experiments.
The naming of each part is exactly the same as Arc1. They
are:
UP_RIGHT, RIGHT_UP, RIGHT_DOWN, DOWN_RIGHT, DOWN_LEFT,
LEFT_DOWN, LEFT_UP and UP_LEFT.
Additional constants defined include:
UPPER_HALF = RIGHT_UP | UP_RIGHT | UP_LEFT | LEFT_UP
LOWER_HALF = LEFT_DOWN | DOWN_LEFT | DOWN_RIGHT | RIGHT_DOWN
LEFT_HALF = UP_LEFT | LEFT_UP | LEFT_DOWN | DOWN_LEFT
RIGHT_HALF = DOWN_RIGHT | RIGHT_DOWN | RIGHT_UP | UP_RIGHT
These constants can be found in the header file GRADARC.H
- 24 -
GRAD User's Manual June 7, 1987
The arcs drawn are affected by the plot style selected. Due
to the way an ellipse is drawn, the style of the arc may not be
uniform. The result would be better if the style setting is
symmetrical. (i.e. the bits when read from left to right or right
to left are the same)
EXAMPLES
(1) Earc1(50,50,30,60,UPPER_HALF);
(2) SetStyle(0xc3c3);
Earc1(100,100,30,60,UPPER_HALF | LOWER_HALF);
First example will draw the upper half of the ellipse only.
The second example will draw the whole ellipse but the
circumference is drawn in dotted line style.
FUNCTIONS INCLUDED
Ellipse
9.1.7 Arc2
Arc2(center_x, center_y, radius,
start_degree, degrees);
int center_x, center_y, radius, start_degree, degrees;
RETURN VALUE
none
DESCRIPTION
This function draws a circular arc. The angle of the arc is
specified in terms of degrees. In order words, the circle is
divided into 360 equal divisions. You specify the starting and
ending division to be drawn.
The parameter start_degree can be any value within the
allowable range of an integer. Arc2 will take the positive value
of start_degree mod 360 ( start_degree % 360 ).
The parameter degrees can be any values too. However if it
is larger than 360, it is set to 360. If it is less than or equal
to zero, nothing will be drawn.
The vertically upward direction is considered to be the
reference line. start_degree is the angle of the line joining the
starting point of the arc and center and the reference line
measured in clockwise direction. degrees is the angle between the
lines joining the starting and ending points to the center.
Immediately after execution of Arc2, you can get the
coordinates of the starting and ending points by using the
function ArcPoint. See the description later in this chapter.
EXAMPLES
(1) Arc2(100,100,50,270,180);
(2) Arc2(200,100,50,90,180);
- 25 -
GRAD User's Manual June 7, 1987
Example 1 draws the upper half of a circle. Example 2 draws
the lower half of a circle.
FUNCTIONS INCLUDED
Arc1, Circle
9.1.8 Earc2
Earc2(center_x, center_y, horiz_axis, vert_axis,
start_degree, degrees);
int center_x, center_y, horiz_axis, vert_axis;
int start_degree, degrees;
RETURN VALUE
none
DESCRIPTION
Earc2 is very similar to Arc2. It draws elliptical arcs
instead of circular arc. The angle of the arc is specified in
terms of degrees. In order words, the ellipse is divided into 360
divisions. (note I do not say equal division.) You specify the
starting and ending division to be drawn.
The parameter start_degree can be any value within the
allowable range of an integer. Arc2 will take the positive value
of start_degree mod 360 ( start_degree % 360 ).
The parameter degrees can be any values too. However if it
is larger than 360, it is set to 360. If it is less than or equal
to zero, nothing will be drawn.
The vertically upward direction is considered to be the
reference line. Due to the limitation of the algorithm used, all
angles are measured on a output device with aspect ratio (width
of a pixel : height of a pixel) equal to vert_axis/horiz_axis. In
other words, the ellipse appear as a `circle'.
start_degree is the angle of the line joining the starting
point of the arc and center and the reference line measured in
clockwise direction. degrees is the angle between the lines
joining the starting and ending points to the center.
Immediately after execution of Earc2, you can get the
coordinates of the starting and ending points by using the
function ArcPoint. See the description later in this chapter.
EXAMPLES
(1) Earc2(100,100,60,30,270,180);
(2) Earc2(200,200,60,30,90,180);
First example draws the upper half of an ellipse. Second
example draws the lower half of an ellipse.
FUNCTIONS INCLUDED
Ellipse, Earc1
- 26 -
GRAD User's Manual June 7, 1987
9.1.9 ArcPoint
ArcPoint(start_x, start_y, end_x, end_y);
int *start_x, *start_y, *end_x, *end_y;
RETURN VALUE
none
DESCRIPTION
Using this function is only meaningful immediately after the
execution of Arc2 or Earc2. If these are any other GRAD function
calls in between, the values return may be incorrect.
The return values are stored in the four parameters given.
They are the (logical) coordinates of the starting and ending
points of the arc just drawn without considering the window
setting. That means if part of the arc is outside the window, the
values returned is exactly the same when the window is larger
than the arc.
EXAMPLE
Arc1(100,100,50,10,30);
ArcPoint(&sx, &sy, &ex, &ey);
Line(sx, sy, 100, 100); /* join the starting and ending
Line(ex, ey, 100, 100); point to the center */
A sector is drawn.
FUNCTIONS INCLUDED
none
9.2 Hints
Circle, Arc1 and Arc2 are special cases of Ellipse, Earc1
and Earc2. They are provided because drawing circles are several
times faster than drawing ellipse. If in one of your program, you
use ellipse most of the time and only requires drawing circles
several times, then you may use ellipse to draw circles instead
in order to reduce program size.
Similarly, Arc1 and Earc1 work faster than Arc2 and Earc2
respectively. Use Arc1 and Earc1 whenever possible.
ArcPoint is used with Arc2 and Earc2 only. It cannot be used
with Arc1 and Earc1.
Besides using Arc1, Arc2, Earc1 and Earc2 to draw arcs, you
can also use Circle and Ellipse to draw arcs. The technique is to
define a window less than the complete circle or ellipse. So only
part of the circle or ellipse is visible. This is useful when you
do not need to draw an arc of exactly how many degrees.
Sometimes, you may want to draw a circle or a sector and
then divided that into several smaller sector. You may draw each
small sectors individually but a better techniques is to draw the
largest sector after combining the small ones then draw lines to
divided that. In order to find the points on the circumference,
- 27 -
GRAD User's Manual June 7, 1987
you should first define the window equal to the center of the
circle (or ellipse). Since the window only include the center
point, the arc is not actually drawn but the end points of the
arc are stilled calculated. See the example in GRADEGS.GCM.
When you want to know the end points of a arc but without
actually drawing it out, you must not define the window outside
the circle because Circle is clever enough not to draw it but it
is not clever to skip the drawing if the window is equal to the
center point.
- 28 -
GRAD User's Manual June 7, 1987
10 4-connected Region Filling
Region filling functions are very useful and powerful.
However, you must be very careful when using them because if your
area you wished to fill is not enclosed by a proper boundary,
then the `paint' will leaks out may make your frame very `dirty'.
The region filling functions in GRAD will fill a 4-connected
region. The definition of a 4-connected region is:
All pixels in a 4-connected region can be reached one from
the other by a sequence of any of the four one-pixel moves:
up, down, left, right, without crossing any boundary
pixel(s).
A boundary pixel is defined by its state (either set or reset).
The state for boundary pixels depends on the plot type using at
that time. It will be explained later in the functions
description.
To fill a 4-connected region, you need to give the
coordinates of any one point in the region, regions filling
functions will look for every pixels in the region by themselves.
Using any point in the region as the starting point would give
the same result. (Remark: but the speed of filling may have a
slight difference. Furthermore, in current implementation of
PatternFill, this statement is not completely true. It will be
explained later when the function is described.)
All pixels outside the window defined are consider in the
state same as the boundary pixels. In other words, no `paint'
will be painted outside the window. That means when you may fill
a completely blank frame to a pattern you want because maximum
window size is the frame size.
I try to give a precise description of what the functions
will do and will not do in different situation. However most of
them are common sense. If you have any problem in understanding
what I said above, try to do some experiments and them come back.
The functions that will be described in this chapter are:
SolidFill Set all pixels in the region to the
same state.
PatternFill Fill the region with a user specified
pattern.
10.1 Functions Description
10.1.1 SolidFill
SolidFill(x,y);
int x,y;
RETURN VALUE
none
DESCRIPTION
- 29 -
GRAD User's Manual June 7, 1987
SolidFill will set all pixels in the 4-connected region
containing (x,y) to the same state. The state depends on the plot
type selected at that time. The boundary pixel state is the same
as the state used for filling. If plot type is 0 (OR type), the
region will be set to set state. If plot type is 1 (AND type),
the region will be set to reset state. If plot type is 2 (XOR
type), the state used will depend on the initial state of the
starting point (x,y). If it is reset, the region will set to set
state, otherwise the region will set to reset state.
SolidFill requires temporary storage from the stack for
working memory. The amount of memory required depends on the
complexity of the region. If you see the message saying that
insufficient working memory for filling, you should increase the
stack size and try again. (Look at your C compiler reference
manual to see how to increase the stack size.) You are not
required to purposely increase the stack size whenever you use
fill functions because working storage of 40 bytes are sufficient
for most situation. (Default stack size in most C compiler is at
least 2K bytes.)
EXAMPLES
(1) PlotType(0);
Arc2(100,100,45,150);
ArcPoint(&x1, &y1, &x2, &y2);
Line(x1,y1,100,100);
Line(x2,y2,100,100);
SolidFill(100,100);
(2) /* Assume the frame is completely blank at this time */
PlotType(2);
Circle(100,100,50);
SolidFill(100,100);
SolidFill(100,100);
In the first example, a sector of 150 degree is filled. In
the second example, you will see the circle filled and then
erased. Read the description above for explanation.
FUNCTIONS INCLUDE
PatternFill
10.1.2 PatternFill
PatternFill(x,y,patptr,0);
int x,y,*patptr;
RETURN VALUE
none
DESCRIPTION
PatternFill is very similar to SolidFill except that it
fills the region in user specified pattern and it has one
limitation in current implementation.
- 30 -
GRAD User's Manual June 7, 1987
patptr is a pointer pointing to a integer array of size 16.
The lower order 8 bit will be displayed on the left of the higher
order 8 bit. So you have to swap the lower and higher byte in
defining your pattern. There is no restriction on what the
pattern should look like. It can be completely set or reset.
Owing to some implementation problems, the current version
of PatternFill can only guarantee filling of simple regions.
Simple region means the region within the outer boundary does not
contain any pixel(s) in the same state as the boundary.
Otherwise, part of the region may not be filled.
The actual operation of PatternFill is like this: The front
line of filling after the first line is drawn will not change
direction. It will continue goes up or down. Therefore, in some
cases, it can fill area other than simple region. For example, a
small rectangle inside a much larger one and the starting point
is either above or below the small rectangle inside the large
rectangle, then the whole region will be filled. If the starting
point is at the right of the small rectangle, the region on the
left of the small rectangle will not be filled.
Although PatternFill is not a complete implementation of
4-connected region filling function, it is sufficient for most
application such as filling pie charts, bar charts etc.
The fourth parameter is not used in current implementation
but it must be set to 0 in order to be compatible with future
version of PatternFill.
EXAMPLE
static int pattern[16]={
0x1111, 0x2222, 0x4444, 0x8888,
0x1111, 0x2222, 0x4444, 0x8888,
0x1111, 0x2222, 0x4444, 0x8888,
0x1111, 0x2222, 0x4444, 0x8888 };
PlotType(0);
Box(100,100,10,50,2,2);
PatternFill(105,105,pattern,0);
The Box drawn in the example will be filled with shaded
lines.
FUNCTIONS INCLUDED
SolidFill
10.2 Hints
- 31 -
GRAD User's Manual June 7, 1987
11 Text Characters Related Functions
A character in GRAD can be completely blank or a block up to
about 120 by 120 pixels(can be change easily during
re-comilation). Font files are loaded into memory during
execution time so that you can access to different type of font
easily.
Currently, two types of font files are supported. First type
is fixed size font. Every character in the file occupy the same
space. The second type is variable size font. Some people call it
proportional spacing characters. The type of the font file is
transparent to the user except in some situation when the exact
size and position of a character or a string of characters are
important, then you may need to know whether it is fixed size or
variable size. More on this later in this chapter.
The functions that will be described in this chapter are:
LoadFont Load a font file into memory.
SelectFont Select the active font type.
RemvFont Remove the font from memory.
WriteStr Write a string of character using the current
font selected.
ReadStr Read a string from keyboard
NextXY get the next coordinates for WriteStr or
ReadStr
11.1 Functions Description
11.1.1 LoadFont
font_number=LoadFont(fontfilename);
int font_number;
char *fontfilename;
RETURN VALUE
A font number
DESCRIPTION
fontfilename is a DOS file name. When LoadFont is executed,
the whole font file will be loaded into memory. It is kept in
memory until it is removed by the function call RemvFont or
termination of GRAD. When error occurs, font number 0 will be
returned. You may test for zero to perform your own error
processing. See also SelectFont.
POSSIBLE ERROR CONDITION
a. Insufficient Memory
font number zero will be returned
b. Too Many Fonts Loaded
The maximum number of fonts allowed to exist simultaneously is
a system parameter. If the number is exceed, font number zero
will be returned.
c. File Not File
- 32 -
GRAD User's Manual June 7, 1987
The specified DOS file is not found. Font number 0 is
returned.
EXAMPLE
font1=LoadFont("E9X14.FON");
FUNCTIONS INCLUDED
RemvFont
11.1.2 SelectFont
ret=SelectFont(font_number);
int ret, font_number;
RETURN VALUE
If -1 is returned, it means the font number given does not
exist or the font number is not assigned to any font. Otherwise
the original font number will be returned.
DESCRIPTION
It selects the current active font number. The font number
is obtained from the function LoadFont except font number zero
which is predefined as the font in BIOS. It contains pattern for
ASCII character 0 to character 127. It is the default font and a
permanent font (means always available) in GRAD.
EXAMPLE
if ((old_font=SelectFont(font_number)) == (-1))
printf("Font %d does not exist\n",font_number);
. . .
. . . use font_number as current font
. . .
SelectFont(old_font); /* return to original font */
FUNCTIONS INCLUDED
SelectFrame
11.1.3 RemvFont
ret=RemvFont(font_number);
int ret, font_number;
RETURN VALUE
A return value of 0 means successful. -1 means the font
number does not exist or the font number is not assigned to any
font.
DESCRIPTION
It removes the font from GRAD and the memory occupied will
be deallocated.
EXAMPLE
if (RemvFont(font_number)==(-1))
printf("Font %d does not exist\n",font_number);
FUNCTIONS INCLUDED
- 33 -
GRAD User's Manual June 7, 1987
LoadFont
11.1.4 WriteStr
WriteStr(options, direction, x, y, string, x_off, y_off);
int options, direction, x, y, x_off, y_off;
char *string;
RETURN VALUE
none
DESCRIPTION
WriteStr is the most complicated function provided in GRAD
but it is not difficult to use once you understand it. Firstly, I
will describe some basic concepts.
Each character in GRAD may be different size but they all
considered to be a rectangular box, we called it a character
cell. Size of a character cell is the same for every character in
the fixed size font file. But they may be different for every
character in variable size font file. The width of the character
cell is called cell width and the height is called the cell
height. They are parameters in the font file. Sometimes, the
character pattern may be larger than the character cell in some
special cases but that will be ignored in the time being.
There are a total of seven parameters for WriteStr. They
will be described one by one below. The constants are defined in
the include file "GRADIO.H"
a. direction is only meaningful when AUTO_MOVE options is used
(described below). It controls the direction of the string
printed. Available selections are:
LEFT [default], move left after each character
DOWN_LEFT moves down and left after each character
DOWN moves down after each character
DOWN_RIGHT moves down and right after each character
RIGHT moves right after each character
UP_RIGHT moves up and right after each character
UP moves up after each character
UP_LEFT moves up and left after each character
b. options are divided into 4 sets. They control the referencing
point of a character cell, clearing of character cell,
operation mode and movement of text pointer. Only one
selection from each set can be used at a time. Selections
from different set should be combined using the OR ( | )
operator. Each set of options will be described separately.
A. Referencing point options tells the given point (x,y)
located in a character cell. Available selection are:
BOTTOM_LEFT is the default and it is most suitable when
direction LEFT is used.
BOTTOM_CENTER is most suitable when direction UP or DOWN is
selected.
BOTTOM_RIGHT is most suitable when direction UP is
selected.
- 34 -
GRAD User's Manual June 7, 1987
TOP_LEFT is most suitable when direction DOWN is
selected.
TOP_CENTER is most suitable when direction UP or DOWN is
selected.
TOP_RIGHT is most suitable when direction RIGHT is
selected.
LEFT_CENTER is most suitable when direction LEFT or RIGHT
is selected.
RIGHT_CENTER is most suitable when direction LEFT or RIGHT
is selected.
B. Clearing of Character Cells. Although the options are
provided, you are not encourage to use it and you should
avoid using it whenever possible. There are two reasons.
First one is the side effect problem. Since characters in
GRAD may have different sizes. Clearing of a character cell
may leave part of a larger character under that character
cell. Another reason is efficiency problem. If you want the
characters written on a clear area, you should clear the
whole area first and then use WriteStr without clearing
option. It will be much faster. However, in some situation,
use of this options is unavoidable so they are provided.
Available selections are:
NO_CLEAR the default. Do not clear the character cell
before writing.
CLEAR_CELL reset all the pixels within the character
cell.
FILL_CELL set all the pixels within the character cell.
INVERSE_CELL the effect of this option depends on the plot
type being used. If plot type 0 is used, the
character cell will be cleared. If plot type
1 is used, the character cell will be filled.
If plot type 2 is used, the character cell
will be inverted.
C. Two operation mode is provided. They are:
WRITE the default. Perform all operations specified in
the other options and then write the characters
to the frame.
NO_WRITE Perform all other operations specified in other
options but the characters are not written to the
frame.
D. Text pointer movement options controls the update of the
pointer after each character is written. Available
selections are:
AUTO_MOVE the default. After writing of character, the text
pointer will be update according to the direction
and the cell height and cell width of the
character just written in addition to the offset
value for x and y coordinate specified in the
function call.
FIX_MOVE ignore direction and the character cell
information. Update the text pointer using only
the offset value specified.
VAR_MOVE Update the text pointer using the user specified
function in addition to the offset value
specified. This option allows the user to place
- 35 -
GRAD User's Manual June 7, 1987
the characters wherever he wants. The option will
be described in full in the section "using
SPACING_FUNC" in the chapter "Advance Topics".
c. x and y are the starting coordinates.
d. string is a null terminated string which is printed using the
current active font.
e. x_off and y_off are the offset value which will be added to
the text pointer after each character is written.
EXAMPLES
1. WriteStr(0,0,10,100,"This is a test!",0,0);
2. WriteStr(0,0,10,200,"This is a test!",2,0);
3. PlotType(1);
WriteStr(TOP_LEFT | SET_CELL,DOWN,10,300,
"This is a test!",0,0);
The first example is the simplest form. It uses default
options. The second example is the same as the first one except
the spacing between the characters are larger. 2 extra pixels in
the horizontal directions are added to the text pointer after
each character. The third example will write the string in
reverse video from top to down.
FUNCTIONS INCLUDED
(writec)
11.1.5 ReadStr
ReadStr(buffer, max_len, startx, starty, mode,
cursor, end_of_input);
char *buffer;
int max_len, startx, starty, mode, cursor, end_of_input;
RETURN VALUE
number of characters entered
DESCRIPTION
ReadStr reads a line of input from the keyboard, echo each
character typed and put them into buffer.
buffer is a character array where the input is stored. The
string is null terminated and no other control
characters will be stored.
max_len is the length of the buffer. Maximum number of
characters can be entered is max_len - 1.
startx, starty is the starting coordinate of the baseline for
echoing the characters entered.
mode controls how the cursor will appear.
NO_CURSOR no cursor is displayed but the area
under the cursor is cleared
DISP_CURSOR just display the cursor
- 36 -
GRAD User's Manual June 7, 1987
BLINK_CURSOR the cursor character turns on and off
REVERSE_CURSOR it keeps reversing the cursor
You may only use one of the above 4 options at a time
but it may combine with the next option.
SHOW_EOI shows end of input character when
return is pressed.
cursor the character used for cursor
end_of_input the character displayed at the end of the line if
SHOW_EOI option is specified in mode.
There are two special key in ReadStr. The return key will
terminate the input line and the backspace key will delete the
last character typed on the line if any. All other control
characters are ignored. If more characters are input than the
buffer can hold, all excess characters will be discarded.
EXAMPLE
char line[80];
ReadStr(line,80,0,100,BLINK_CURSOR | SHOW_EOI, 0x5f, 17);
It reads input from the keyboard and put them into line.
Maximum length is 79 characters plus a carriage return.
FUNCTIONS INCLUDED
writec, WriteStr, HorzLine, PlotType
11.1.6 NextXY
NextXY(x,y);
int *x, *y;
RETURN VALUE
values are returned in the 2 parameters. They are
coordinates for next character in ReadStr and WriteStr.
DESCRIPTION
NextXY is for ReadStr and WriteStr only. It returns the next
coordinate in ReadStr and WriteStr if there is any more
characters to display. It should be called immediately after
ReadStr and WriteStr otherwise the result may be destroyed.
EXAMPLE
WriteStr(0,0,10,100,"Enter your name : ",0,0);
NextXY(&x, &y);
ReadStr(line,80,x,y,BLINK_CURSOR,0x5f,0x5f);
It print the string "Enter your name : " and then prompt for
input immediate after the string.
FUNCTIONS INCLUDED
none
- 37 -
GRAD User's Manual June 7, 1987
12 Block Operations
The functions provide ways to move data between frames and
between frame and external data. Each block must be a rectangle.
When data are moved to a GRAD frame, it can be OR, AND or XOR
with the original data according to the plot type setting.
The functions that will be described in this chapter are:
BlockCopy Copy a block between 2 frames
BlockSave Move a block to a disk file
BlockLoad Load a block from a disk file
12.1 Function Description
12.1.1 BlockCopy
ret=BlockCopy(src_frame, src_x, src_y,
dest_frame, dest_x, dest_y,
length, height);
int ret, src_frame, src_x, src_y, dest_frame, dest_x;
int dest_y, length, height;
RETURN VALUE
0 means OK. -1 means one of the frame specified is invalid.
DESCRIPTION
BlockCopy is used to copy a rectangular block from the
source frame (src_frame) to the destination frame (dest_frame)
specified. The two frame number can be the same or different but
they must exist at the time the call is made. If the frame
numbers are the same, the source block and the destination block
must not overlapped with each other otherwise unpredictable
result may be obtained.
In the current implementation, the lower 4 bit of dest_x
must be equal to lower 4 bit of src_x. If not, BlockCopy will
force them to be equal by copying the lower 4 bit of src_x to
dest_x.
When the block is copied to the destination frame, the block
will be OR, AND or XOR with the original data in the destination
block according to the current plot type selected.
Both the window setting of the source and destination frame
will affect the size of the block actually copied. BlockCopy will
not copy any data from area outside the window of the source
frame and it will not write to any area outside of the window of
the destination frame.
BlockCopy will not affect the current frame number. The
source and destination frame may be different from the current
frame selected.
EXAMPLE
frame1=CreateFrame(960,480);
- 38 -
GRAD User's Manual June 7, 1987
frame2=SelectFrame(frame1);
Ellipse(480,240,450,230);
BlockCopy(frame1,0,0,frame2,0,0,960,480);
Let's assume the Color Graphics Adapter display memory is
the original frame selected before execution of the example above
and the window size is equal to frame size. frame2 will contain
the frame number of the CGA frame. The length and height
specified in the BlockCopy command is 960 and 480 respectively.
However, the resolution of a CGA is only 640 and 200. Therefore
only the upper left corner (640 by 200) of frame1 is copied.
FUNCTIONS INCLUDED
none
12.1.2 BlockSave
BlockSave(start_x, start_y, filename, width, height);
int start_x, start_y, width, height;
char *filename;
RETURN VALUE
none
DESCRIPTION
BlockSave will save the block specified in the current
active frame to a file with the given filename. All data if any
in that file will be replaced by the new data. If that file does
not exist, a new file will be created. The coordinates of the top
left corner of the block is given by start_x and start_y. The
width and height is specified in the corresponding parameter with
the same name. If the block does not lay completely inside the
window, only the portion inside the window is saved. If the block
is completely outside the window, no data will be saved and the
file will not be affect if it already exist or the file will not
be created.
The actual width and height of the block will be stored in
the data file also. The format of the data file is described in
the appendix.
EXAMPLE
BlockSave(0,0,"test.blk",100,100);
Assume the whole block is inside the window, then the block
100 by 100 pixels will be stored in the file "test.blk".
FUNCTIONS INCLUDED
BlockLoad
12.1.3 BlockLoad
ret=BlockLoad(start_x, start_y, filename);
- 39 -
GRAD User's Manual June 7, 1987
int ret, start_x, start_y;
char *filename;
RETURN VALUE
0 means success. -1 indicates error. It may due to file not
found or bad file.
DESCRIPTION
BlockLoad is the counterpart of BlockSave. It loads a block
file into the current frame with the top left hand corner at
(start_x, start_y). In current implementation, the lower bit of
start_x must be equal to the lower 4 bit of the original start_x
(in BlockSave) when BlockSave is used. If not, BlockLoad will
force them to match by changing the start_x of BlockLoad.
The way the data is stored in the current frame is
controlled by the current plot type.
This is no explicit command to load part of a block file
only. However, you may do this by setting the window to exclude
part of the block to be loaded. No data will be loaded outside
the current window setting.
EXAMPLE
BlockLoad(400,0,"test.blk");
FUNCTIONS INCLUDED
BlockSave
- 40 -
GRAD User's Manual June 7, 1987
13 Frame Printing
Before you try to print a frame using the function described
in this chapter, make sure that you have the correct driver for
your printer. Customizing of printer driver is discussed in
Appendix A.
Since different printers may use different ways in
controlling graphics printing and you may have different printer
driver, it is impossible to discuss every possible cases. Hence,
I would discuss the general situation and use EPSON FX printer as
an example. If you have problem in understanding, try to ask a
friend who owns a EPSON FX or compatible printer to explain to
you.
The function that will be explained in this chapter is:
PrintFrame
Dump the current selected frame to the printer any may
overlay with text data.
Allowing the merge printing of text and graphics data
greatly increase the speed of printing when both text and
graphics data are required because it don't need to convert the
text into graphics data before printing by the program.
Use of software printer spooler can speed up the printing.
Size of the buffer should be 16K bytes or more.
13.1 Function Description
13.1.1 PrintFrame
PrintFrame(options, page, line, line_height, offset);
int option, line, line_height, offset;
char *page[];
RETURN VALUE
none
DESCRIPTION
This function merge print the text data given if any and the
current active frame to the printer. The parameters are explained
below. The constants can be found in GRADIO.h
a. options consist of 2 sets of options for the control of
vertical and horizontal printing density. Available options
depends on the printer driver you have. The options given
below are for the EPSON FX printer driver.
A. Vertical density
NORMAL_DOT The spacing between 2 vertical dot on paper
is equal to the spacing between 2 pins on the
print head in the printer.
SMALL_DOT The spacing between 2 vertical dot is 1/3 of
- 41 -
GRAD User's Manual June 7, 1987
spacing between 2 pins on the print head.
I think the best way to explain these is to see an example.
The EPSON FX printers can print up to 216 dots per inch
vertically. However, the spacing between pins in the print
head is 1/72 inch (3 times of 1/216). In order to print at
high resolution, the printer spaces 1/216 inch after the
first pass and the second pass and then spaces 22/216
inches (2/216 + 22/216 = 8/72) and repeat the procedure
again. As a result, it can print 216 dots vertically per
inch.
When you specify the SMALL_DOT option, PrintFrame will take
advantage of this features and the print the frame at high
resolution. Otherwise, the frame will be printed at 72 dots
per inch vertically.
B. Horizontal density
LOW_DENSITY The resolution is 60 dots per inch
MEDLOW_DENSITY The resolution is 72 dots per inch
MEDIUM_DENSITY The resolution is 80 dots per inch
HIGH_DENSITY The resolution is 120 dots per inch
ULTRA_DENSITY The resolution is 240 dots per inch
Not all EPSON FX printers support all of the above print
mode. Read you manual to see which modes are supported.
b. page is a pointer to an array of character pointer. PrintFrame
gets the text data using this pointer. Also see the example
below.
c. line is the number of line given in the array pointer by page.
If it is zero, PrintFrame will not look at page and no text
data overlaid with the frame in printing.
d. height is the number of points between the base lines of two
rows of text data. A point is defined as the distance between
two pins on the print head. For example, the distance two pins
on the print head of EPSON FX printer is 1/72 inch. If you
want to print at 6 lines per inch, you should specify 12 (72
divided by 6) as height.
e. offset specify the distance of the first line of text data
from the top of the frame. offset is in term of point as
defined just a second ago. Negative offset means the text data
is shifted downward relative to the top of the frame. Positive
offset means the text data is shifted upward.
The text data and the frame need not be the same length and
width. However the text data must not longer than 1 line because
that will cause auto line feed of the printer and the text data
must not contain any control codes that will cause the moving of
paper. There is an exceptional case when the printer is in near
letter quality mode, the printer will automatically line feed for
1/216. This is OK.
FUNCTIONS INCLUDED
- 42 -
GRAD User's Manual June 7, 1987
none
- 43 -
GRAD User's Manual June 7, 1987
14 The DRAW function
Draw function provides features similar turtle graphics. The
main idea is to keep track of the current coordinates and use
these coordinate when a function required a coordinate number.
This help the user to draw complex figures without worrying the
exact coordinates.
The command string for draw function is very compact. This
also help keeping the program size small. On the other hand, use
of Draw functions will include all GRAD functions that is
accessible from Draw at link time even if you do not use them.
This will increase the executable file size.
14.1 Draw
Draw(string, parm1, parm2);
char *string;
int parm1, parm2;
RETURN VALUE
none
DESCRIPTION
string is the Draw command string. The syntax will be
described later. parm1 and parm2 will be assigned to X and Y of
marker 0. It will be explained further when we talk about marker.
The command string can be any length but it has to be in ASCII
and terminated by a NULL character.
On entry, the current environment is saved. If there is no
environment slot available, it is an irrecoverable error and
program will normally terminated unless a function is registered
for error handling. On exit, the environment is not restored
automatically. However, Draw provides an environment restore
command (EO). You can use it at the end of the command string to
restore the environment before exit.
The syntax for the command string is given below.
:= stands for define as
| means or
[ ] means this is optional
{ } select one of the entities inside
CMD_STRING := CMD_UNITS
CMD_UNITS := CMD_UNIT | CMD_UNIT CMD_UNITS
CMD_UNIT := CMD_CODE[$] [PARAMETERS]
CMD_CODE := LETTER LETTER
PARAMETERS := PARAMETER | PARAMETER , PARAMETERS
PARAMETER := DECIMAL | HEXADECIMAL | {&|%}DIGIT{X|Y}
DIGIT := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
DECIMAL := [+|-]DIGITS
DIGITS := DIGIT | DIGITDIGITS
HEXDIGIT := DIGIT | A | B | C | D | E | F | a | b | c | d
| e | f
HEXADECIMAL:= 0XHEXDIGITS | 0xHEXDIGITS
HEXDIGITS := HEXDIGIT | HEXDIGITHEXDIGITS
- 44 -
GRAD User's Manual June 7, 1987
LETTER is defined as letter A to Z and a to z
If there is any space separating any 2 entities in the above
definition, it means zero, one or spaces are allowed except when
this is ambiguity. For example, the last parameter in the
preceding CMD_UNIT is a hexadecimal number. Since a hexadecimal
number may contain a to f and A to F which are also belong to
LETTER. Therefore it is necessary to insert a space after the
last parameter if that is a hexadecimal number and the next
CMD_CODE begins with letter a to f or A to F.
Below is a table showing the command codes, number of
parameters required, whether the current coordinates is affected
and a brief description. P# (# represent a digit from 1 to 9)
stands for the parameter #. For example P1 stands for the first
parameter.
CMD_ no. of affect
CODE param. coord. Description
---- ----- ------ -----------
RS 0 No Reset the window to frame size, logical
origin to physical coordinate 0. The
current coordinates number will change to
reflect the change of the coordinate
system if necessary.
LF 1 Yes move left P1 pixels.
RT 1 Yes move right P1 pixels.
UP 1 Yes move up P1 pixels.
DN 1 Yes move down P1 pixels.
UL 1 Yes move up and left P1 pixels.
UR 1 Yes move up and right P1 pixels.
DL 1 Yes move down and left P1 pixels.
DR 1 Yes move down and right P1 pixels.
JR 2 Yes move left and down P1 and P2 pixels
respectively. P1 and P2 can be negative to
stands for moving right and up.
JA 2 Yes jump to (P1,P2)
/* NW and PU only affects the commands */
/* LF, RT, UP, DN, UL, UR, DL, DR, JR */
above
*/
WR 0 No write (selects plot type OR)
ER 0 No erase (selects plot type AND)
RV 0 No reverse (selects plot type XOR)
NW 0 No set flag such that when the current
coordinate move, no ink is left on the
frame.
PU 0 No Pen Up for the during next command. The
effect is similar to NW except it only
last for 1 command only.
HL 2 Yes draws a horizontal line starting at
current coordinate and length P1 to the
left and width P2 downward. P1 and P2
cannot be negative.
- 45 -
GRAD User's Manual June 7, 1987
VL 2 Yes draws a vertical line starting at current
coordinates and length P1 downward and
width P2 to the left. P1 and P2 cannot be
negative.
SO 0 set the current position as the new
origin. Current coordinates are set to
zero to reflect change of coordinate
system.
SY 1 No set line style to P1
AS 1 No set arc drawing specification for use by
CI (circle) and EL (ellipse).
MK 1 No put current coordinates into marker P1.
MK 3 No put (P2,P3) into marker P1
WN 2 No the 2 corners of the window is the current
location and (P1,P2).
DY 1 No delay for P1/100 seconds. It is not very
accurate.
CI 1 No current coordinates are the center, P1 is
the radius. It also affected by the arc
specification setting.
EL 2 No current coordinates are the center, P1 is
the length of the horizontal axis and P2
is the length of the vertical axis.
RE 2 No draws a rectangle with upper left corner
at current location and width and height
are P1 and P2 respectively.
BX 4 No draws a box with upper left corner at
current location. Width and height are P1
and P2 respectively. P3 and P4 are the
width of the horizontal and vertical lines
of the box.
FC 1 No draws a solid circle with radius P1
FE 2 No draws a solid ellipse with horizontal and
vertical axes equal to P1 and P2
respectively.
ES 0 No environment variables save into the slot
allocated on entry.
EO 1 environment restore from the slot using
parameter P1. KEEP_SLOT is implied. It
does not affect the value of current
coordinates but it may affect the location
of the origin and hence affect the actual
location.
FI 0 No Fill the region starting from current
location.
Marker is a unique feature provided by draw so it will be
discussed in detail. Draw process a total of 10 markers. Each
marker can store 2 integer values in the registers called X and
Y. Coordinate numbers are usually stored but you may store any
integer values in the marker. Marker 0 is a special marker which
initially values in registers X and Y are the second and third
parameters given when Draw is called.
There are two ways to retrieve a marker. The first way is to
retrieve the absolute value of the markers. It is done by typing
%#X or %#Y (# stands for a digit 0..9) in the place where a
parameter is expected. The second way is to retrieve the value of
- 46 -
GRAD User's Manual June 7, 1987
the marker relative to the current coordinates. You can do this
by typing &#X or &#Y in the place where a parameter is expected.
When the X part is retrieved, the return value will be relative
to current X coordinate. Similarly when Y part is retrieved.
In the table given above, some functions when used will
affect the current coordinates. However, if you add a '$'
immediately after the command code, then the current coordinates
will not be affected. Adding a '$' is only meaningful for
functions that is stated 'Yes' in the table above.
EXAMPLE
Draw("NW RT6 AS0xc0 EL5,9 UP9 WR RT228",0,0);
Draw("NW DN9 AS0x03 EL5,9 RT5 WR DN304",0,0);
Draw("NW LF6 AS0x0c EL5,9 DN9 WR LF228",0,0);
Draw("NW UP9 AS0x30 EL5,9 LF5 WR UP304",0,0);
The above lines will draw a rectangle with round corner.
FUNCTIONS INCLUDED
Line, Plottype, Dot, HorzLine, VertLine, SetStyle, SetOrg,
RelOrg, SetWin, Circle, Arc1, Ellipse, Earc1, FillCircle,
FillEllipse, EnvSave, EnvRsto, SolidFill, PatternFill.
- 47 -
GRAD User's Manual June 7, 1987
15 Miscellaneous Functions
This chapter will describe those functions that do not fit
into any other chapter in this manual. It includes:
GRADinit initialize the GRAD environment
cleanup clean up everything before exit
XHLine extend to left and right from a point
writec write a single character
15.1 Functions Description
15.1.1 GRADinit
GRADinit();
RETURN VALUE
none
DESCRIPTION
GRADinit initialize the GRAD environment and test the
processor speed and put the result into TEN_MS. See also the
description of TEN_MS. It should be called before using any GRAD
functions. Once GRADinit is called, you must call cleanup before
exit. Read the description of cleanup in next section.
EXAMPLE
GRADinit();
FUNCTIONS INCLUDED
cleanup
15.1.2 cleanup
cleanup(exit_code);
int exit_code;
RETURN VALUE
none
DESCRIPTION
cleanup must be called if GRADinit was called. If the
exit_code is non-zero, cleanup will terminate the program after
clean up using the exit code. If exit_code is zero, cleanup will
return control to the caller.
EXAMPLE
cleanup(1);
Cleans up and terminate the program.
FUNCTIONS INCLUDED
GRADinit
- 48 -
GRAD User's Manual June 7, 1987
15.1.3 XHLine
ret=XHLine(x,y,boundary,leftx,rightx);
int x,y,boundary,*leftx,*rightx;
int ret;
RETURN VALUE
-1 is returned if (x,y) is already in boundary state or
(x,y) is outside the window. If return value is not -1,
coordinates of the left most and right most point of the line
drawn are returned in leftx and rightx.
DESCRIPTION
You give any point (x,y) and specify the boundary state in
the search. A horizontal line will be drawn by extending to the
left and right. If value of boundary is 0, the drawing of the
line in that direction stops when it encounters any pixel in set
state. If the value of boundary is non-zero, the drawing stops
when it encounters any pixel in reset state. The left most and
right most coordinates of the line is returned. Of course the
line cannot go beyond the window. All pixels outside the window
are considered in boundary state.
The line will be drawn using current plot type and current
line style. If the point (x,y) is in boundary state, no dot will
be drawn and -1 is returned.
EXAMPLE
VertLine(50,50,100,1);
VertLine(150,50,100,1);
XHLine(100,100,0,&leftx, &rightx);
XHLine will draw a horizontal line from (51,100) to
(149,100). 51 and 149 will be returned in leftx and rightx
respectively.
FUNCTIONS INCLUDED
none
15.1.4 writec
writec(x,y,ch,width,height,options);
int x,y,ch,*width,*height,options);
RETURN VALUE
width and height of the character box are returned in width
and height field in the parameter list.
DESCRIPTION
writec output a single character (ch) using current selected
font to the current frame. (x,y) is the reference point for the
character. The actual meaning depends on the options field. The
interpretation of options is exactly the same as the options
field in WriteStr except it does not have the text pointer
movement options (category D).
You should avoid using this function as much as possible.
- 49 -
GRAD User's Manual June 7, 1987
EXAMPLE
writec(100,100,0x5f,&width, &height, 0);
FUNCTIONS INCLUDED
WriteStr, HorzLine, PlotType
- 50 -
GRAD User's Manual June 7, 1987
16 Advance Functions
In this chapter, all other GRAD functions that is not
described in the preceding chapters will be described. These
functions are usually more advance. Only experience users should
try to use them. The functions to be described include:
calcaddr calculate address of the coordinate
exchange exchange the upper and lower byte of int
fr_read read a word from the current frame
fr_write write a word to the current frame
phyaddr calculate physical address
writetype plot type other than AND, OR and XOR
16.1 Functions Description
16.1.1 calcaddr
addr=calcaddr(x,y);
int far *addr;
int x,y;
RETURN VALUE
logical address where (x,y) in current active frame is
located.
DESCRIPTION
It will calculate the address where the pixel (x,y) in
current frame is located. The address return may not be physical
address. You must not try to read or write it directly. You
should use the functions fr_read and fr_write to read and write.
EXAMPLE
addr=calcaddr(200,100);
if (fr_read(addr) & DOTVALUE[200 & 0x0f]) {
printf("pixel (200,100) is set");
} else {
printf("pixel (200,100) is reset");
}
16.1.2 exchange
ret=exchange(value);
unsigned int ret, value;
RETURN VALUE
the upper and lower byte of value is swapped and return as
function result.
DESCRIPTION
The upper and lower byte of the parameter is swapped.
EXAMPLE
printf("%4x\n",exchange(0x1234));
- 51 -
GRAD User's Manual June 7, 1987
3412 is the value printed.
16.1.3 fr_read
ret=fr_read(addr);
int far *addr;
unsigned int ret;
RETURN VALUE
the value at the logical address addr
DESCRIPTION
It reads the value by the address given. You should only
read from the active frame otherwise it is not guaranteed that
the result is correct.
EXAMPLE
addr=calcaddr(200,100);
if (fr_read(addr) & DOTVALUE[200 & 0x0f]) {
printf("pixel (200,100) is set");
} else {
printf("pixel (200,100) is reset");
}
16.1.4 fr_write
fr_read(addr,value);
int far *addr;
unsigned int value;
RETURN VALUE
none
DESCRIPTION
It write the value into the address given. You should only
write to the active frame otherwise it is not guaranteed that the
result is correct. fr_write use the current plot type in writing.
EXAMPLE
addr=calcaddr(200,100);
fr_write(addr, DOTVALUE[200 & 0x0f]);
It writes the pixel (200,100).
16.1.5 phyaddr
addr=phyaddr(x,y);
int x,y;
int far *addr;
RETURN VALUE
physical address of the pixel (x,y) in current active frame.
DESCRIPTION
- 52 -
GRAD User's Manual June 7, 1987
phyaddr is very similar to calcaddr except the return
address is always a physical address. If the whole frame is not
accessible all the time (e.g. JLASER), immediately after
execution of phyaddr, the line containing (x,y) will be
accessible.
EXAMPLE
int far *addr;
addr=phyaddr(x,y);
16.1.6 writetype
writetype();
RETURN VALUE
none
DESCRIPTION
set the plot type to overwrite. DON'T try to use it unless
you know what you are doing!
EXAMPLE
writetype();
- 53 -
GRAD User's Manual June 7, 1987
17 System Dependent Functions
The functions described in this chapter are not standard
GRAD library functions. That means they are not always in the
library. It depends on the output device configured in your GRAD
system you are using.
17.1 Functions Description
17.1.1 settext
settext();
RETURN VALUE
none
DESCRIPTION
It is available when Hercules and Color Graphics Card is
used. The function is to change the display mode to text mode.
EXAMPLE
settext();
17.1.2 setgraph
setgraph();
RETURN VALUE
none
DESCRIPTION
It is available when Hercules or Color Graphics Card is
used. The function is to change the display mode to graphics
mode.
EXAMPLE
settext();
17.1.3 initjlsr
initjlsr();
RETURN VALUE
none
DESCRIPTION
This is used to initialize the JLASER mode to allocate
memory for graphics data. You are not normally required to use it
because it is included in GRADinit.
EXAMPLE
initjlsr();
- 54 -
GRAD User's Manual June 7, 1987
17.1.4 cleanjlsr
cleanjlsr();
RETURN VALUE
none
DESCRIPTION
This is used to clean up the JLASER mode by deallocate the
memory for graphics data. You are not normally required to use it
because it is included in cleanup;
EXAMPLE
cleanjlsr();
17.1.5 dumpjlsr
dumpjlsr();
RETURN VALUE
none
DESCRIPTION
dumpjlsr will activate JLASER card to dump the memory to the
LASER printer. You may also print the data in memory using
PrintFrame.
EXAMPLE
dumpjlsr();
- 55 -
GRAD User's Manual June 7, 1987
18 GRAD Global Variables
Some of the variables in GRAD may be used by the user. You
should have at least 2 months of experience with GRAD before you
try to use these variables.
18.1 TEN_MS
int TEN_MS;
DESCRIPTION
TEN_MS contains a value that is proportion to the central
processor speed. It is only a relative number and the value may
not be the same when GRAD is run twice in a row but they should
be close.
A IBM PC/XT running at 4.77MHz gives a count approximately
equal to 333. If a processor is ten times faster, the value
should be about 3330.
18.2 DOTVALUE
unsigned int DOTVALUE[16]
DESCRIPTION
DOTVALUE gives the relative dot position in a word. Each
word comprise 16 dots numbered from 0 to 15. Dot 0 is the left
most dot and 15 is the right most dot when display.
DOTVALUE[n] where n is number from 0 to 15 gives the value
of the corresponding dot in the word. See also fr_read and
fr_write.
18.3 PRE_GRAD_ERR_LEVEL, POST_GRAD_ERR_LEVEL
int PRE_ERROR_LEVEL, POST_ERROR_LEVEL;
DESCRIPTION
The error level in GRAD runs from 0 to 10. PRE_ERROR_LEVEL
defines the lowest error level you want to take control before
the GRAD default error handling routine process the error.
POST_ERROR_LEVEL defines the lowest error level you want to take
control after GRAD default error handling routines print the
error message and before it aborts the program or does recovery.
See also PRE_ERROR_FUNC, POST_ERROR_FUNC and error handling
in the chapter "Advance Topics".
18.4 PRE_ERROR_FUNC, POST_ERROR_FUNC
void (*PRE_ERROR_FUNC)(), (*POST_ERROR_FUNC)();
DESCRIPTION
The declaration of the functions should be like this:
- 56 -
GRAD User's Manual June 7, 1987
#include <stdarg.h>
int user_error_routine();
extern (*PRE_ERROR_FUNC)();
.
.
.
main()
{
.
.
PRE_ERROR_LEVEL=4; /* or the level you want */
PRE_ERROR_FUNC=user_error_routine;
.
.
}
void user_error_routine(error_level, error_nu, arg_ptr)
int error_level, error_nu;
va_list arg_ptr; /* points to additional argument
from caller */
{
.
.
}
It is similar for POST_ERROR_FUNC.
18.5 SPACING_FUNC
int (*SPACING_FUNC)();
DESCRIPTION
This is for used with WriteStr. See the section on "using
SPACING_FUNC" in the chapter "Advance Topics".
18.6 XLIMIT, YLIMIT
int XLIMIT, YLIMIT;
DESCRIPTION
They are the maximum physical coordinates in the current
frame. They change when active frame change. You must not change
these values.
18.7 ORGX, ORGY
int ORGX, ORGY;
DESCRIPTION
(ORGX, ORGY) is the physical coordinate of the origin in
logical coordinate system.
- 57 -
GRAD User's Manual June 7, 1987
18.8 WINX1, WINX2, WINY1, WINY2
int WINX1, WINX2, WINY1, WINY2;
DESCRIPTION
WINX1, WINX2, WINY1 and WINY2 stores the lower and upper
limit of x coordinate and lower and upper limit of y coordinate
of the current window respectively.
- 58 -
GRAD User's Manual June 7, 1987
19 Advance Topics
19.1 Error Handling
When GRAD functions detects a error, they will call GRADerr
with a error level code and error number. It will issue an error
message and takes appropriate action. However GRAD also provides
a simple way for the users to take control when error is
detected. There are four variables declared for error handling:
int PRE_ERROR_LEVEL, POST_ERROR_LEVEL;
void (*PRE_ERROR_FUNC)(), (*POST_ERROR_FUNC)();
Firstly, let's talk about the error level in GRAD. All
errors in GRAD is classified into 4 categories -- Warning (level
2), Recoverable Error (level 4), Unrecoverable Error (level 6)
and GRAD Program Error (level 10).
The default action in GRAD is to print an error message for
all level of error. If that is a level 2 error (warning), it will
return control to the program. Otherwise, it will abort the
program.
You may change the default action of GRADerr by changing the
four variables mentioned above. You may take control before
GRADerr issues an error message or after. PRE_ERROR_LEVEL and
POST_ERROR_LEVEL defines the lowest level of error you want to
see before GRAD issues an error or after. When GRADerr finds that
you want to take control, it will call the function defined in
PRE_ERROR_FUNC or POST_ERROR_FUNC. If PRE_ERROR_LEVEL or
POST_ERROR_LEVEL is greater than or equal to 10 (GRAD Program
Error), user error routine will never be called. GRADerr always
handle level 10 and above error.
After functions defined in PRE_ERROR_FUNC or POST_ERROR_FUNC
have processed the error situation, they may return control to
GRADerr, abort the program by calling cleanup or do a longjmp. If
user program takes control using PRE_ERROR_FUNC, error message
will not be issued by GRADerr even after it takes control again.
However, both PRE_ERROR_FUNC and POST_ERROR_FUNC may be called if
error level is greater than PRE_ERROR_LEVEL and POST_ERROR_LEVEL.
There is no way to continue the execution of a GRAD function
if it detects a error condition with error level greater than 2
(warning).
Users may define there own error level and use GRADerr to
handle that. In that case, you must write your own user handling
routine or modify GRADerr (not recommended). Below is a short
example.
#include <stdio.h>
#include <GRADVAR.h>
#include <stdarg.h>
void usererror1(), usererror2();
- 59 -
GRAD User's Manual June 7, 1987
main()
{
char line[80];
GRADinit();
setgraph();
PRE_ERROR_LEVEL=4;
PRE_ERROR_FUNC=usererror1;
POST_ERROR_LEVEL=2;
POST_ERROR_FUNC=usererror2;
while (1) {
CreateFrame(960,792);
PlotType(1);
HorzLine(10,280,XLIMIT,25);
PlotType(0);
ReadStr(line,80,10,300,2,0x5f,0x5f);
LoadFont(line);
}
}
void usererror1(errlevel, errnu, arg_ptr)
int errlevel, errnu;
va_list arg_ptr;
{
extern char *GRADERRMSG[];
printf("I am usererror 1:");
vprintf(GRADERRMSG[errnu],arg_ptr);
printf("\n");
}
void usererror2(errlevel, errnu, arg_ptr)
int errlevel, errnu;
va_list arg_ptr;
{
printf("I am usererror2\n");
}
This program will get error very soon. You can type in a
wrong font file name and get a level 2 error. After several
times, you will get out of memory error (level 6) because each
new frame occupy almost 93K bytes of memory.
19.2 Using SPACING_FUNC
The function which address is stored in SPACING_FUNC should
return a integer. Zero means go on. A non-zero values tells
WriteStr to stop immediately. It may also modify the content of
the some of the variables in WriteStr through the address given
in the parameters.
Below is a simple example of using SPACING_FUNC. The spacing
between the characters increase by 2 every time.
#include <stdio.h>
#include <GRADVAR.h>
- 60 -
GRAD User's Manual June 7, 1987
#include <GRADio.h>
int increasing();
int spacing;
main()
{ int x,y;
GRADinit();
setgraph();
spacing=0;
SPACING_FUNC=increasing;
WriteStr(VAR_MOVE,0,10,100,
"This is a special test 123456",0,0);
getch();
settext();
cleanup(0);
}
increasing(curx, cury, w, h, remaining)
int *curx, *cury, w, h;
char *remaining;
{
*curx+=w+spacing;
spacing+=2;
return(0);
}
The function increasing will only get control if VAR_MOVE
option is used in WriteStr. Every time when it gets control, it
has five parameters -- curx, cury is the coordinate of the
reference point of the character just written. w and h are the
width and height of the character box of the character just
written. remaining points to the remaining part of the string to
be written. You may modify the remaining part of the string on
the fly. For example, you may set the next character to null so
that WriteStr will terminate immediately. Of course you may
return a non-zero value to terminate WriteStr too.
Another application of SPACING_FUNC is to do justification.
On the first call to WriteStr, specify NO_WRITE and collect
information on the line. Then call WriteStr again to insert
microspaces to justify the line.
Within SPACING_FUNC, you may call other GRAD functions
including WriteStr too! But be careful, the loop must be
terminate in some way, otherwise you will get the stack overflow
error very soon.
- 61 -
GRAD User's Manual June 7, 1987
20 Sample Programs
20.1 MPrint and Interp
USAGE
MPrint [options] GRAD-command-file text-file-to-be merge
Interp GRAD-command-file
EXAMPLE
Mprint -v1 test.gcm test.txt
Print graphics data in high density.
DESCRIPTION
Below are the simple syntax rules for Interp and Mprint.
` ' means optional, | means or , { } means selection
STMT := [ VARIABLE = ] FUNCTION
VARIABLE := identifier
FUNCTION := identifier ( PARAMETERS ) ;
PARAMETERS := PARAMETER , PARAMETERS | PARAMETER
PARAMETER := EXPRESSION
EXPRESSION := NUMBER | STRING | VARIABLE | & VARIABLE | COLUMN
| LINE
NUMBER := +NATURAL | -NATURAL
NATURAL := 0xHHHH | decimal digits
STRINGS := "character string"
H := decimal digits | A | B | C | D | E | F | a | b | c
| d | e | f
COLUMN := [ {C|c}NATURAL `, NATURAL' ]
LINE := [ {L|l}NATURAL `, NATURAL' ]
In order to facilitate the calculation the coordinates on
the paper in MPrint, you may specify a coordinate in terms of
line and column number. Both line and column number start from 1.
The calculations are based on the character width and height
setting. You may change those values using command line options
in Mprint but Interp always use the default values in Mprint.
No variables can be declared but there are a number of
pre-declared variables.
a. temp1, temp2, temp3, env1, env2, env3, font1, font2, font3,
font4, frame1, frame2, frame3, x1, x2, y1, y2 are all
integer variables.
b. line is a character pointer to a 132-byte area. It is mainly
for ReadStr function.
c. pattern1, pattern2 and pattern3 are pattern definition for
use with PatternFill only.
- 62 -
GRAD User's Manual June 7, 1987
'&' operator can only be used with integer variables only.
Moreover, only integer variables can appear on the left hand side
of '=' (assignment).
No any kind of arithmetic operations is allowed in both
Mprint and Interp. However, you may draw lines with same
coordinate numbers but at different location by setting origin at
different coordinates.
PrintPage in Interp is a dummy function. Execution of
PrintPage in Interp will suspend the interpretation of the
command file until any key is pressed on the keyboard.
Furthermore, after a key is pressed, the screen will be cleared.
PrintPage in Mprint will merge print the current selected
frame and the text file if specified. The frame will be cleared
after printing.
MPrint also provides a number of options which is not
provided in Interp. The number inside the parentheses
-W frame width (960)
-H frame height (792)
-w character width in terms of pixels (12)
-h character height in terms of pixels (12)
-c column offset (0)
-r row offset (0)
-p line per page (66)
-d horizontal density (4)
-v vertical density (0)
All the default value is for EPSON printer. You may need to
change the default values for different printer.
There are a number of examples for MPrint and Interp. They
illustrate most of the features of Interp and MPrint. You can
learn a lot more about GRAD library by studying those examples.
20.2 Rotate
USAGE
rotate input-FON-file output-FON-file
EXAMPLE
rotate AMR7.fon AMR7U.fon
DESCRIPTION
The input and output font file name cannot be the same. The
naming convention is to append U, R or D after the normal font
file name to indicate that font file is normally for writing
upward, to the right or downward.
This program will rotate a font file in anti-clockwise
direction for 90 degree. For example, AMR7.fon after rotation
should have the name AMR7U.fon. If it is rotated again, the file
name should become AMR7R.fon.
- 63 -
GRAD User's Manual June 7, 1987
20.3 Size
USAGE
size -s# [options] input-file output-file
EXAMPLE
size -s1 e6x8.fon e12x8.fon
DESCRIPTION
This program is to change the size of the font file.
Allowable options are:
-s0 reduce height by half
-s1 double the height
-s2 double the width
-m0 ink dominate (default)
-m1 prefer ink
-m2 prefer white space
-m3 white space dominate
-m option is only useful in reducing the size of the font.
During reduction, several pixels will be reduced to 1 pixel. If
ink donimate option is used, the resulting pixel is black if any
one of the source pixels is black. Similarly for white space
dominate. If prefer ink option is used, the resulting pixel is
black if the number of black pixel is more than or equal to the
number of white pixel. If prefer white space option is used, the
resulting pixel is black if the number of black pixel is MORE
than the number of white pixel.
In this version of size, -m0 and -m1, -m2 and-m3 are the
same. In order to provide future compatibility, all 4 options are
valid.
20.4 DispFont
USAGE
DispFont
DESCRIPTION
Enter a font file name when it asks for one. Enter the ASCII
code of the character you want to see. The character and the
enlarger character will be displayed. A return or a negative
ASCII number will terminate the program.
20.5 SwPrt (Sideway)
USAGE
swprt [options] text-file-name
EXAMPLE
swprt -fAMR7D.fon -s35 -H1920 -W792 -L3 -v1 -d3 test.txt
DESCRIPTION
The options provided are: (values inside parentheses are the
default value)
- 64 -
GRAD User's Manual June 7, 1987
-W Width of the print out (792). This is the length of the
frame created for output. This value should be a simple
fraction (1/2, 1/3 or 1/4) or a integral multiple of the
length of paper. If -v1 (described below) option is used
and -L (described below also) is set to a value greater
than 1, the width should be a integral multiple of the
number of vertical unit per point. In other words, for
EPSON printer, the value is 3, for OKI Microline 192, the
value is 2.
-H Height of the print out (960). This is the width of the
paper. This number is related to the horizontal density
(-d option) setting.
-v Vertical density (0). Any non-zero value will be
considered as 1. See PrintFrame for explanation.
-d Horizontal density (4). Also see PrintFrame for
explanation. This value is suitable for EPSON printer
only. You should set it to 2 for OKI printer if you want
to use other default values.
-s Spacing between any 2 base line (11). This value is very
likely to be changed when different font file is used.
See -f option below.
-f Font file name. (S6X8D.fon) This is the font used in
printing. When use other font file, remember to change
the spacing between lines using -s option described
above.
-t Top margin (36). This is the margin on the right side of
the paper.
-b Bottom margin (36). This is the margin on the left side
of the paper.
-L Text length (1). This field controls the number of 'page'
for the text. If text length is set to 2, that means the
width of the text is twice the specified width (-W). In
this way, you may print very long data without creating a
very large frame. The -L setting times the -W setting
must not exceed 30000. This value should be more than
enough.
The default values will print 132 characters by 80 lines per
page on a EPSON compatible printer.
20.6 Tex2GRAD
USAGE
TeX2GRAD TeX-PXL-file GRAD-FON-file
EXAMPLE
TeX2GRAD amr10.pxl amr10.fon
- 65 -
GRAD User's Manual June 7, 1987
DESCRIPTION
TeX2GRAD converts a TeX pixel files to GRAD font file.
During the conversion, ASCII character 32 (' ') is forced to be a
space with width equal to 9/16 of the design size.
The TeX pixel file must be a type 1002 pixel file and the
magnification field in the file must contain the resolution of
the output device the pixel file is designed for times 5. For
example, a pixel file for a laser printer with 300dpi, the
magnification field must contain 1500 decimal. The pixel files
from TEXTSET meets all of the above requirements.
- 66 -
GRAD User's Manual June 7, 1987
Appendix A : Customizing of Printer Control Codes
General Information
Two printer drivers for EPSON FX-80 and OKI ML192 are
distributed with the GRAD library. If you have one of these
printers or a compatible one, you just need to follow the
installation instruction and you will be able to print on your
printer. Otherwise, go on reading this chapter.
You can only configure GRAD to use 8 bit graphics printer
with the information here and the included source files. If your
graphics printer is 24-pin printer or it only accepts 7 bit data,
you need the source code of GRAD library to do the configuration.
Information for special customizing accompany the source code.
To do customizing, you need a Microsoft C compiler version 4
and you may need a macro assembler also in some cases.
There are three files involved in the customizing process.
a. prtcntl.c defines the control code sequence for printing
graphics and paper feeding.
b. prt.asm contains routines for converting data in frame to
data for printing.
c. pframe controls the number of dots printer vertically per
pass and the number of dots per point.
Each of these will be discussed later. Firstly, let me
define some of the terms first. A point in publishing means a
length approximately equal to 1/72 inch. However, a point here
means the distance between 2 pins on the print head. Vertical
unit is the smallest distance that the printer can move
vertically. The length of both point and vertical unit are
printer dependent. However, a point must be an integral multiple
(can be 1) of vertical unit.
a. prtcntl.c
In prtcntl.c, there are 8 variables declared. 5 of them are
structure prtcmd. prtcmd is used to store printer control codes
sequence. It contains 5 members.
length the length of the sequence from 0 to 8.
factor the number that will multiple with the number to be
included in the control sequence.
numh the high order byte of the scaled number in the
sequence. The value can be from -1 to length-1. -1
means the high order byte is not used.
numl the low order byte of the scaled number in the
sequence. The value can be from -1 to length-1. -1
means the low order byte is not used.
code the code sequence is stored here. Max. number of
character is 8.
GRAD requires 5 kind of control sequences.
skp control sequence for moving the paper forward a
certain number of points. Note, it is point not
vertical unit.
- 67 -
GRAD User's Manual June 7, 1987
skd control sequence for moving the paper forward a
certain number of vertical unit. Only used when
SMALL_DOT option is used in PrintFrame.
setp set the line feed spacing of the printer to the
specified number of points. It is only used at the
end of PrintFrame to set the printer back to six
line per inch. If skp and skd does not affect the
line feed spacing, you may set setp to null by
setting the length field to 0.
header is a array of struct prtcmd. It contains control
sequence to turn the printer into different density
graphics mode. The sequence is output immediately
before the graphics data.
endg contains the control sequence that append at the end
of graphics data in order to terminate the graphics
mode and cause the printer to actually print out the
data.
Other 3 variables are:
MAXPSIZ is the maximum number of dots that the printer can
print in different density.
NHEADER contains the number of entries in the array header
and MAXPSIZ. Don't forget to change this number when
you change the number of entries in header and
MAXPSIZ.
sixlpi is the value that will be used with setp to set the
printer back to 6 line per inch at the end of
PrintFrame.
b. prt.asm
It is a assembly program to convert data in frame to data
for printing. The data in a frame is stored line by line and the
printer usually requires data to be send 8 (or more) lines a
time. prt is the routine for conversion. prtgc is the routine for
putting data into the buffer and optionally do additional
checking for special pattern. See the case studies for more
information.
c. pframe.obj
pframe controls the number of vertical dots sent each time
and the number of vertical unit per point. Source code of pframe
is not included with GRAD library. However two version of
pframe.obj is provided: (1) 8 dots each time and 3 vertical units
per point (EPSON FX-80) (2) 8 dots each time and 2 vertical units
per point (OKI ML192).
In the remaining part of the chapter, we will study the code
for EPSON printer and OKI printer in order to provide a example
of customizing.
- 68 -
GRAD User's Manual June 7, 1987
EPSON FX-80 Driver Case Study
IN EPSON FX-80 printer, it does not have a control sequence
to forward the paper a specified number of points. So I have to
set the line spacing to the desired number and do a line feed.
The sequence for setting line spacing is 3 characters long and
the fourth character is a line feed.
The length of each vertical unit is 1/216 inch but the
length of a point is 1/72 = 3/216 inch. Therefore the factor
field is 3 in skp. Only a one byte value is allowed in the
control sequence so the numh field is set to -1 (not used) and
numl is set to 2 (the third character). skd is set in a similar
way except the factor field is 1 this time. If you have a EPSON
FX-80 manual, you would find that the control sequence for
setting line spacing is not the same as defined in setp. setp
contains two extra characters. These are for IBM graphics printer
or compatibles but it should still work for FX-80 printer.
EPSON printer requires a length field as part of the control
sequence for graphics printing. It requires the total number of
bytes of graphics data following the sequence. The length field
is 16 bit. Therefore both the numh and numl fields are set.
If your printer don't have 80 dots per inch mode (640 dots
per line on 8 inch paper), you may used the sequence for 240 dots
per inch and set the factor field to 3. PrintFrame will
automatically insert 2 null characters after each graphics data
byte.
endg for EPSON is just a return character.
MAXPSIZ values are the number of dots per inch times 8. If
you have a FX-100, the values should be the number of dots per
inch times 13.5.
If you look at prt.asm, you would find that the difference
between EPSON and OKI driver is in two main area. Firstly in prt,
FX-80 mode use rcl (rotate circular left) while OKI mode use rcr
(rotate circular right). It is because the least significant bit
of each byte is printed at the bottom in FX-80 but it is printed
at the top in ML192. Another difference is in prtgc. OKI has an
additional check for 03. It will be explained in the case study
for OKI ML192.
OKI ML192 Driver Case Study
OKI ML192 use a scheme completely different from FX-80 in
printing graphics. It has control sequence for forwarding paper
without changing the line spacing setting. Therefore no setp
sequence is required. Furthermore, the line spacing before and
after printing is the same and it may not be six line per inch.
In ML192, it uses the control code 03 to enter graphics mode
and the sequence 03 02 to exit from graphics mode. No total
length of data is required to send to the printer. If the
graphics data contains the pattern 03, it has to be duplicated
- 69 -
GRAD User's Manual June 7, 1987
(i.e. 03 03) to indicate the 03 is a data byte and not command
code. This is the reason for a special checking for 03 in
prt.asm in OKI mode.
endg contains 03 02 to indicate end of data which are
appended at the end of graphics data.
sixlpi is not used in OKI driver. Therefore it can be any
value but it has to be defined.
Additional Information
Before you do the customizing, you should first try to see
any body has done the customizing for your printer make the
driver available on the BBS.
When you do the customizing, probably you need to modify
prtcntl.c yourself. But you may not need to modify prt.asm
because you may use the OKI or EPSON version. Then you choose a
suitable version of pframe for your printer. If you need a
special version of pframe, you have to either buy the source code
or see other printer drivers available have a version suitable
for you or not. With the source code and the knowledge of C and
assembly language, customizing for most kind of printer will be
easy. Additional information is provided with source code.
- 70 -
GRAD User's Manual June 7, 1987
Appendix B : Customizing of Output Device
Customizing for output device have a lot of variations. You
may only need to change a single line to rewrite several routines
in customizing. You also need some experiences with GRAD before
trying to do customizing otherwise it is very difficult.
Therefore only general information will be given. You should
study the source codes provided yourself to find out what do you
need to change.
Three routines are related to customizing. They are
calcaddr.asm, plottype.asm and ftable.c. Most of the hardware
dependent values are defined in calcaddr.asm including the
address of video memory, default font pattern address and the
routines for calculating address by giving x and y coordinates.
plottype.asm contains the lowest level memory accessing routine
for reading and writing. ftable.c contain code for defining the
characteristics of the output device.
Three drivers are provided for Color graphics adapter,
Hercules graphics adapter (full or half mode) and JLASER card.
- 71 -
GRAD User's Manual June 7, 1987
Appendix C : Font File Structure
There are 2 types of font files. They are distinguish by the
type code stored in each font file. Each of them will be
described separately.
Fixed Size Character (type 0)
The File format is shown below. If that field is a 2 byte
integer, lower byte (less significant) will be stored first and
then the higher byte (more significant). The word inside the
bracket is the field name.
Byte Description
0 ID = 51 decimal
1 to n-1 [comment] A string in ASCII terminated by a NULL
character. The string can be any length less than
or equal to 255.
n [type] The type code. 0 in fixed size font file
n+1, n+2 [nochar] Number of character in this file
n+3, n+4 [start] The starting number. For example, only
pattern for graphic ASCII characters are
available. That means the first pattern is for
ASCII 0x20. Therefore, this field should contains
0x0020.
/* the fields below will be described in more detail later */
n+5 [width] width of the character cell
n+6 [ink-width] ink width of the pattern
n+7 [ink-height] ink height of the pattern
n+8 [left-margin] left-margin of the pattern
n+9 [top-line] the highest line number
n+10 [cell-height] height of the character cell
n+11 [default] the default character number
n+12 to n+15 reserved
n+16 to end of file are the pattern information
Let's take an example using E9X14.fon (a font file
containing 9 by 14 patterns). The vales for byte n to byte n+11
are:
00 00 01 00 00 09 08 0E 00 0A 0E 7F
The font file contains pattern in the format of type 0 (1st
byte). The number of pattern is 256 (0x0100 2nd and 3rd bytes)
and it starts it ASCII 0 (0x0000 4th and 5th byte). The width of
each character including spacing is 9 dots (0x09 6th byte).
However, only 8 dots (0x08 7th byte) of data are given in the
file and the pattern given starts at the first dot (0x00 9th
byte). So the 9th dots is assumed to be 0. The height of the
character cell is 14 (0x0E 8th byte). The pattern starts at 10
lines above the base line. That means the descendent part is 3
dots. If a character given does not have a corresponding pattern
in the file (greater than 255), the ASCII character 255 (0x7f
last byte) will be written instead.
- 72 -
GRAD User's Manual June 7, 1987
The pattern is stored line by line according to the ink
width and ink height. For example, a character pattern of ink
width equal to 9 and height equal to 14. 28 bytes are required to
store one character. The character when display is in the form
below:
0 7 8 15
+-------+-------+
| 0 | 1 |
+-------+-------+
| 2 | 3 |
+-------+-------+
. . . . . . .
+-------+-------+
| 26 | 27 |
+-------+-------+
Only bits 0 to 8 of every 2 bytes are used.
Variable Size Character (type 1)
The File format is shown below. If that field is a 2 byte
integer, lower byte (less significant) will be stored first and
then the higher byte (more significant). The word inside the
bracket is the field name.
Byte Description
0 ID = 51 decimal
1 to n-1 [comment] A string in ASCII terminated by a NULL
character. The string can be any length less than
or equal to 255.
n [type] The type code. 1 in variable size font
file
n+1, n+2 [nochar] Number of character in this file
n+3, n+4 [start] The starting number. For example, only
pattern for graphic ASCII characters are
available. That means the first pattern is for
ASCII 0x20. Therefore, this field should contains
0x0020.
n+5 to n+7 reserved
n+8 [default] the default character number
n+9 to n+15 reserved
n+16 to n+21 width, ink width, left margin, top line, cell
height information of first character.
n+22 to n+27 same kind of information for second character.
.
. information of all characters in the file
.
n+16+6*nochar to end of the file are the pattern data of the
characters
The pattern data are stored exactly as described in the
section for fixed size character except each character are
independent of each other.
- 73 -
GRAD User's Manual June 7, 1987
Appendix D : Block File Structure
The format of a block file is very simple. It contains a
header and then comes the data. The structure when represented in
C syntax is like this:
struct header_format {
unsigned char ID;
unsigned int header_length : 4;
unsigned int x_offset : 4;
int length, height;
int dummy;
} ;
struct blockfile {
struct header_format header;
int data[height][((x_offset+length+15) >> 4)];
};
The ID is equal to 101 decimal in this version.
header_length is in term of 4-bytes. That means the length of the
header must be multiple of 4 bytes. The header_length field in
block files created by GRAD contain the value 2 now because the
header length is 6 bytes plus 2 byte dummy. The maximum header
length is hence 64 bytes. You may include your own information in
the header but remember to change the header_length field.
We will return to x_offset later. Let's talk about length
and height fields first. length and height contain the actual
number of pixels in the block horizontally and vertically
respectively.
Since the data array is declared as integer array, the
number of bytes per line must be even. Since the length field can
be any number, that means some of the bits in the data do not
contain useful information. In order to make the program more
efficient, the starting bit of actual data of each line in the
file is the same as that when it is in memory as part of the
frame. x_offset is used to store the starting pixel number for
the first word (2 byte) in each line. x_offset may contain value
from 0 to 15.
The most significant bit of a byte is displayed as the left
most pixel of the byte. The earlier bytes of the line are stored
at the left of a frame. This is the same as Color Graphics and
Hercules Graphics.
- 74 -
GRAD User's Manual June 7, 1987
Appendix E : Functions Summary
Function Description
Arc1 Draws arc (part of a circle)
Arc2 Draws arc (part of a circle)
ArcPoint Gives 2 end points of Arc2 or Earc2
BlockCopy Copy a data block between 2 frames
BlockLoad Load a data block from disk
BlockSave Save a data block to disk
Box Draws a box
calcaddr Calculates the word address in byte of a point
Circle Draws a logical circle
cleanup Cleans up everything
CopyBlock Copys a block within or between frame(s)
CreateFrame Creates a new frame
Dot Draws a single dot
Draw Interprete a string of command
Earc1 Draws arc (part of an ellipse)
Earc2 Draws arc (part of an ellipse)
Ellipse Draws an ellipse
EnvSave Saves the environment
EnvRsto Restores the environment
FillCircle Draws a solid circle
FillEllipse Draws a solid ellipse
fr_read read a word
fr_write write a word according to plot type
HorzLine Draws a horizontal line of any width
GRADinit Initialize GRAD environment
Line Draws a line between any 2 points
LoadFont Loads a font file from disk
NextXY Gives next (x,y) location for ReadStr or WriteStr
PatternFill Fill the area by the pattern specified
phyaddr calculate physical address
PlotType Selects system plot type
PrintFrame Print a frame to Printer
ReadStr Read a line from standard input
Rectangle Draws a rectangle
RelOrg Set origin
RemvFont Removes a font from memory
RemvFrame Removes a frame from GRAD and release the memory
ResetWin Reset the window to the same size as the frame
SelectFont Selects the current font number
SelectFrame Selects the active frame
SetOrg Set origin
SetStyle Sets line style
SetWin Set a rectangular window
SolidFill Entirely fill a region
VertLine Draws a VertLine in any width
writec writes a single character
writetype set to over write
WriteStr writes a string
XHLine A horizontal line extends at both end
- 75 -
GRAD User's Manual June 7, 1987
Appendix F : System Limits
There are two types of system limits. First type of limit is
caused by the compiler, the algorithms, the memory available
...etc. If one wants to change these limits, a lot of changes
have to be made. Another kind of limit is just arbitrary. You may
change these limits by changing a constant and re-compile the
program provided you have the source codes, of course.
Program Limits
a. The absolute maximum physical coordinate must be less than
+32767. In reality, physical coordinate can never get close to
this number because it is limited by the maximum frame size
also.
b. The range of logical coordinate must be within -32768 and
+32767.
c. The maximum horizontal frame size is 4096. You may change this
maximum by changing 2 or 3 modules but I think 4096 is more
than enough in most cases. The absolute maximum vertical size
is 32767. But you will run out of memory before you get close
to this number.
d. The maximum length of the radius for Circle, Arc1, Arc2,
FillCircle must be less than 8192.
e. For Ellipse, FillEllipse, Earc1 and Earc2, square of one of
the axes times another axis must be less then 1E+9. If the
length of both axis is the same, maximum length would be 1000.
It should be sufficient for most application except when you
are working on a high resolution output device such as JLASER
and you need a large ellipse.
f. There are also limits on the length for HorzLine, VertLine and
Line but they are limited by the frame size far before limited
by the algorithm.
Configuration Limits
a. The maximum number of frame that can be exist at the same time
including the default frame is 10. This is controlled by
NFRAME in source listing.
b. The maximum number of font that can be used at the same time
including the font in ROM is 10. This is controlled by
MAXNFONT in source listing.
c. The maximum number of slot for saving environment including
slot 0 is 10. This is controlled by MAX_ENVSLOT.
d. The maximum size of a single character is approximately 2000
bytes. That is about 120 by 120 pixels. This is controlled by
the size of the array CFBUF.
- 76 -
GRAD User's Manual June 7, 1987
e. The maximum length of data on a single pass for the printer is
2048 bytes. This is also controlled by the size of the array
CFBUF.
f. There is no arbitrary limit on the length of string for draw
and WriteStr except by the memory available and the compiler.
- 77 -
GRAD User's Manual June 7, 1987
Appendix G : Error Messages
Below is a list of all possible error message by GRAD
functions. In a strip down version of error handling routine, it
may only print the error number. So the error number is also
given on the left of the message.
Error no.
0 "Undefined Error Number : %d"
1 "invalid environment slot number in EnvSave - %d"
2 "invalid environment slot number in EnvRsto - %d"
3 "environment slot not used - %d"
4 "disk access error in BlockSave"
5 "bad block file"
6 "file not found - %s"
7 "too many frame opened"
8 "not sufficient memory to create new frame - %d*%d"
9 "insufficient stack size for Fill"
10 "PROGRAM ERROR IN %s LINE %d"
12 "bad font type - %d"
13 "too many font files loaded"
14 "bad font file"
15 "not sufficient memory to load new font"
16 "no more environment slot for Draw"
17 "invalid command in Draw - %c%c"
18 "wrong number of parameter given to %c%c in Draw"
19 "a digit expected after '%' or '&' in Draw"
20 "invalid marker number - %d"
21 "disk error in reading font file"
- 78 -
GRAD User's Manual June 7, 1987
Appendix H : List of Header Files
Below is the list of the header files for programs that use
the GRAD library.
/* GRADIO.H */
#define LEFT 0
#define DOWN_LEFT 1
#define DOWN 2
#define DOWN_RIGHT 3
#define RIGHT 4
#define UP_RIGHT 5
#define UP 6
#define UP_LEFT 7
#define BOTTOM_LEFT 0x00
#define BOTTOM_CENTER 0x04
#define BOTTOM_RIGHT 0x01
#define TOP_LEFT 0x03
#define TOP_CENTER 0x06
#define TOP_RIGHT 0x02
#define LEFT_CENTER 0x05
#define RIGHT_CENTER 0x07
#define CLEAR_CELL 0x10
#define FILL_CELL 0x20
#define INVERSE_CELL 0x30
#define WRITE 0x00
#define NO_WRITE 0x08
#define AUTO_MOVE 0x0000
#define FIX_MOVE 0x0100
#define VAR_MOVE 0x0200
/* GRADARC.h */
#define UP_RIGHT 0x01
#define RIGHT_UP 0x02
#define RIGHT_DOWN 0x04
#define DOWN_RIGHT 0x08
#define DOWN_LEFT 0x10
#define LEFT_DOWN 0x20
#define LEFT_UP 0x40
#define UP_LEFT 0x80
#define UPPER_HALF 0xc3
#define LOWER_HALF 0x3c
#define LEFT_HALF 0xf0
#define RIGHT_HALF 0x0f
void Circle(), Arc1(), Arc2(), FillCircle();
void Ellipse(), Earc1(), Earc2(), FillEllipse();
/* GRADENV.h */
int EnvSave(), EnvRsto();
#define KEEP_SLOT 0x8000
#define KEEP_WIN 0x0001
#define KEEP_ORG 0x0002
#define KEEP_STYLE 0x0004
#define KEEP_PLOTTYPE 0x0008
#define KEEP_FRAME 0x0010
- 79 -
GRAD User's Manual June 7, 1987
#define KEEP_FONT 0x0020
/* GRADVAR.h */
extern unsigned int DOTVALUE[];
extern int XLIMIT, YLIMIT;
extern int ORGX, ORGY;
extern int TEN_MS;
extern void (*PRE_ERROR_FUNC)(), (*POST_ERROR_FUNC)();
extern int (*SPACING_FUNC)();
extern int PRE_ERROR_LEVEL, POST_ERROR_LEVEL;
extern int WINX1, WINX2, WINY1, WINY2;
- 80 -